]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-udf.patch
- CONFIG_USB*_NET2280 is not set for now (no dma-coherent memory allocator in 2.4...
[packages/kernel.git] / kernel-udf.patch
1 diff -Nru linux/Documentation/Configure.help linux.new/Documentation/Configure.help
2 --- linux/Documentation/Configure.help  Fri Sep  7 11:18:50 2001
3 +++ linux.new/Documentation/Configure.help      Fri Sep  7 11:32:15 2001
4 @@ -9538,6 +9538,26 @@
5    like lynx or netscape). Say Y here if you want to be able to read
6    Joliet CDROMs under Linux.
7  
8 +UDF Filesystem support (EXPERIMENTAL)
9 +CONFIG_UDF_FS
10 +  This is the new filesystem used by some CDROMS and DVD drivers. Say
11 +  Y if you intend to mount DVD discs or CDRWs written in packet mode,
12 +  or if written to by other UDF utilities, such as DirectCD. Please
13 +  read Documentation/filesystems/udf.txt
14 +
15 +  This filesystem support is also available as a module ( = code which
16 +  can be inserted in and removed from the running kernel whenever you
17 +  want). The module is called udf.o. If you want to compile it as a
18 +  module, say M here and read Documentation/modules.txt. 
19 +
20 +  If unsure, say N.
21 +
22 +UDF read-write support (FOR TESTING ONLY)
23 +CONFIG_UDF_RW
24 +  Say Y if you want to test write support for UDF filesystems.
25 +  Due to lack of support for writing to CDR/CDRW's, this option
26 +  is only supported for Hard Discs, DVD-RAM, and loopback files.
27 +
28  fat fs support
29  CONFIG_FAT_FS
30    If you want to use one of the FAT-based filesystems (the MS-DOS,
31 diff -Nru linux/Documentation/filesystems/00-INDEX linux.new/Documentation/filesystems/00-INDEX
32 --- linux/Documentation/filesystems/00-INDEX    Sun Mar 25 18:31:56 2001
33 +++ linux.new/Documentation/filesystems/00-INDEX        Fri Sep  7 11:32:15 2001
34 @@ -22,6 +22,8 @@
35         - info on using filesystems with the SMB protocol (Windows 3.11 and NT)
36  sysv-fs.txt
37         - info on the SystemV/Coherent filesystem.
38 +udf.txt
39 +       - info and mount options for the UDF filesystem.
40  ufs.txt
41         - info on the ufs filesystem.
42  umsdos.txt
43 diff -Nru linux/Documentation/filesystems/udf.txt linux.new/Documentation/filesystems/udf.txt
44 --- linux/Documentation/filesystems/udf.txt     Thu Jan  1 01:00:00 1970
45 +++ linux.new/Documentation/filesystems/udf.txt Fri Sep  7 11:32:15 2001
46 @@ -0,0 +1,60 @@
47 +*
48 +* ./Documentation/filesystems/udf.txt
49 +*
50 +UDF Filesystem version 0.9.2.1
51 +
52 +If you encounter problems with reading UDF discs using this driver,
53 +please report them to linux_udf@hpesjro.fc.hp.com, which is the
54 +developer's list.
55 +
56 +Write support requires a block driver which supports writing. The current
57 +scsi and ide cdrom drivers do not support writing.
58 +
59 +-------------------------------------------------------------------------------
60 +The following mount options are supported:
61 +
62 +       gid=            Set the default group.
63 +       umask=          Set the default umask.
64 +       uid=            Set the default user.
65 +       bs=                     Set the block size. 
66 +       unhide          Show otherwise hidden files.
67 +       undelete        Show deleted files in lists.
68 +       adinicb         Embed data in the inode (default)
69 +       noadinicb       Don't embed data in the inode
70 +       shortad         Use short ad's
71 +       longad          Use long ad's (default)
72 +       strict          Set strict conformance (unused)
73 +
74 +The remaining are for debugging and disaster recovery:
75 +
76 +       novrs           Skip volume sequence recognition 
77 +
78 +The following expect a offset from 0.
79 +
80 +       session=        Set the CDROM session (default= last session)
81 +       anchor=         Override standard anchor location. (default= 256)
82 +       volume=         Override the VolumeDesc location. (unused)
83 +       partition=      Override the PartitionDesc location. (unused)
84 +       lastblock=      Set the last block of the filesystem/
85 +
86 +The following expect a offset from the partition root.
87 +
88 +       fileset=        Override the fileset block location. (unused)
89 +       rootdir=        Override the root directory location. (unused)
90 +                               WARNING: overriding the rootdir to a non-directory may
91 +                                       yield highly unpredictable results.
92 +-------------------------------------------------------------------------------
93 +
94 +
95 +For more information see:
96 +       http://www.trylinux.com/projects/udf/index.html
97 +
98 +For the latest version and toolset see:
99 +       http://www.csc.calpoly.edu/~bfennema/udf.html
100 +       http://linux-udf.sourceforge.net/
101 +
102 +Documentation on UDF and ECMA 167 is available FREE from:
103 +    http://www.osta.org/
104 +    http://www.ecma.ch/
105 +
106 +Ben Fennema <bfennema@falcon.csc.calpoly.edu>
107 diff -Nru linux/Documentation/ioctl-number.txt linux.new/Documentation/ioctl-number.txt
108 --- linux/Documentation/ioctl-number.txt        Sun Mar 25 18:37:29 2001
109 +++ linux.new/Documentation/ioctl-number.txt    Fri Sep  7 11:32:15 2001
110 @@ -96,6 +96,8 @@
111  'k'    all     asm-sparc/kbio.h, asm-sparc64/kbio.h
112  'l'    00-3F   linux/tcfs_fs.h         in development:
113                                         <http://mikonos.dia.unisa.it/tcfs>
114 +'l'    40-7F   linux/udf_fs_i.h        in development:
115 +                                       <http://www.trylinux.com/projects/udf/>
116  'm'    all     linux/mtio.h            conflict!
117  'm'    all     linux/soundcard.h       conflict!
118  'n'    all     linux/ncp_fs.h
119 diff -Nru linux/MAINTAINERS linux.new/MAINTAINERS
120 --- linux/MAINTAINERS   Fri Sep  7 11:18:22 2001
121 +++ linux.new/MAINTAINERS       Fri Sep  7 11:32:15 2001
122 @@ -1042,6 +1042,15 @@
123  L:     linux-scsi@vger.kernel.org
124  S:     Maintained
125  
126 +UDF FILESYSTEM
127 +P:     Ben Fennema
128 +M:     bfennema@falcon.csc.calpoly.edu
129 +P:     Dave Boynton
130 +M:     dave@trylinux.com
131 +L:     linux_udf@hootie.lvld.hp.com
132 +W:     http://www.trylinux.com/projects/udf/index.html
133 +S:     Maintained
134 +
135  UMSDOS FILESYSTEM
136  P:     Matija Nalis
137  M:     mnalis-umsdos@voyager.hr
138 diff -Nru linux/fs/Config.in linux.new/fs/Config.in
139 --- linux/fs/Config.in  Fri Sep  7 11:18:14 2001
140 +++ linux.new/fs/Config.in      Fri Sep  7 11:32:16 2001
141 @@ -31,6 +31,13 @@
142    # needed by nls/Config.in
143    define_bool CONFIG_JOLIET n
144  fi
145 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
146 +  tristate 'UDF filesystem support (EXPERIMENTAL)' CONFIG_UDF_FS
147 +  if [ "$CONFIG_UDF_FS" != "n" ]; then
148 +    bool '   UDF read-write support (FOR TESTING ONLY)' CONFIG_UDF_RW
149 +  fi
150 +fi
151 +
152  
153  tristate 'Minix fs support' CONFIG_MINIX_FS
154  tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS
155 diff -Nru linux.orig/fs/Makefile linux/fs/Makefile
156 --- linux.orig/fs/Makefile      Wed Nov 21 21:18:15 2001
157 +++ linux/fs/Makefile   Wed Nov 21 21:27:00 2001
158 @@ -19,7 +19,7 @@
159  ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \
160                 reiserfs \
161                 hpfs sysv smbfs ncpfs ufs affs romfs autofs hfs lockd \
162 -               nfsd nls devpts adfs qnx4 efs
163 +               nfsd nls devpts adfs qnx4 udf efs
164  
165  ifeq ($(CONFIG_QUOTA),y)
166  O_OBJS += dquot.o
167 @@ -232,6 +232,14 @@
168    endif
169  endif
170  
171 +ifeq ($(CONFIG_UDF_FS),y)
172 +SUB_DIRS += udf
173 +else
174 +  ifeq ($(CONFIG_UDF_FS),m)
175 +  MOD_SUB_DIRS += udf
176 +  endif
177 +endif
178
179  ifeq ($(CONFIG_AUTOFS_FS),y)
180  SUB_DIRS += autofs
181  else
182 diff -Nru linux/fs/filesystems.c linux.new/fs/filesystems.c
183 --- linux/fs/filesystems.c      Fri Sep  7 11:17:42 2001
184 +++ linux.new/fs/filesystems.c  Fri Sep  7 11:32:16 2001
185 @@ -26,6 +26,7 @@
186  #include <linux/romfs_fs.h>
187  #include <linux/auto_fs.h>
188  #include <linux/qnx4_fs.h>
189 +#include <linux/udf_fs.h>
190  #include <linux/ntfs_fs.h>
191  #include <linux/hfs_fs.h>
192  #include <linux/devpts_fs.h>
193 @@ -163,6 +164,9 @@
194         init_qnx4_fs();
195  #endif
196     
197 +#ifdef CONFIG_UDF_FS
198 +       init_udf_fs();
199 +#endif
200  #ifdef CONFIG_NLS
201         init_nls();
202  #endif
203 diff -Nru linux/fs/udf/Makefile linux.new/fs/udf/Makefile
204 --- linux/fs/udf/Makefile       Thu Jan  1 01:00:00 1970
205 +++ linux.new/fs/udf/Makefile   Fri Sep  7 11:32:16 2001
206 @@ -0,0 +1,16 @@
207 +#
208 +# Makefile for the linux udf-filesystem routines.
209 +#
210 +# Note! Dependencies are done automagically by 'make dep', which also
211 +# removes any old dependencies. DON'T put your own dependencies here
212 +# unless it's something special (ie not a .o file).
213 +#
214 +# Note 2! The CFLAGS definitions are now in the main makefile..
215 +
216 +O_TARGET := udf.o
217 +O_OBJS   := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
218 +               partition.o super.o truncate.o symlink.o fsync.o \
219 +               crc.o directory.o misc.o udftime.o unicode.o
220 +M_OBJS   := $(O_TARGET)
221 +
222 +include $(TOPDIR)/Rules.make
223 diff -Nru linux/fs/udf/balloc.c linux.new/fs/udf/balloc.c
224 --- linux/fs/udf/balloc.c       Thu Jan  1 01:00:00 1970
225 +++ linux.new/fs/udf/balloc.c   Fri Sep  7 11:32:16 2001
226 @@ -0,0 +1,1008 @@
227 +/*
228 + * balloc.c
229 + *
230 + * PURPOSE
231 + *     Block allocation handling routines for the OSTA-UDF(tm) filesystem.
232 + *
233 + * CONTACTS
234 + *     E-mail regarding any portion of the Linux UDF file system should be
235 + *     directed to the development team mailing list (run by majordomo):
236 + *             linux_udf@hootie.lvld.hp.com
237 + *
238 + * COPYRIGHT
239 + *     This file is distributed under the terms of the GNU General Public
240 + *     License (GPL). Copies of the GPL can be obtained from:
241 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
242 + *     Each contributing author retains all rights to their own work.
243 + *
244 + *  (C) 1999-2000 Ben Fennema
245 + *  (C) 1999 Stelias Computing Inc
246 + *
247 + * HISTORY
248 + *
249 + *  02/24/99 blf  Created.
250 + *
251 + */
252 +
253 +#include "udfdecl.h"
254 +#include <linux/fs.h>
255 +#include <linux/locks.h>
256 +#include <linux/quotaops.h>
257 +#include <linux/udf_fs.h>
258 +
259 +#include <asm/bitops.h>
260 +
261 +#include "udf_i.h"
262 +#include "udf_sb.h"
263 +
264 +#define udf_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
265 +#define udf_set_bit(nr,addr) ext2_set_bit(nr,addr)
266 +#define udf_test_bit(nr, addr) ext2_test_bit(nr, addr)
267 +#define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size)
268 +#define udf_find_next_one_bit(addr, size, offset) find_next_one_bit(addr, size, offset)
269 +
270 +#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
271 +#define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
272 +#define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))
273 +
274 +extern inline int find_next_one_bit (void * addr, int size, int offset)
275 +{
276 +       unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
277 +       unsigned long result = offset & ~(BITS_PER_LONG-1);
278 +       unsigned long tmp;
279 +
280 +       if (offset >= size)
281 +               return size;
282 +       size -= result;
283 +       offset &= (BITS_PER_LONG-1);
284 +       if (offset)
285 +       {
286 +               tmp = leBPL_to_cpup(p++);
287 +               tmp &= ~0UL << offset;
288 +               if (size < BITS_PER_LONG)
289 +                       goto found_first;
290 +               if (tmp)
291 +                       goto found_middle;
292 +               size -= BITS_PER_LONG;
293 +               result += BITS_PER_LONG;
294 +       }
295 +       while (size & ~(BITS_PER_LONG-1))
296 +       {
297 +               if ((tmp = leBPL_to_cpup(p++)))
298 +                       goto found_middle;
299 +               result += BITS_PER_LONG;
300 +               size -= BITS_PER_LONG;
301 +       }
302 +       if (!size)
303 +               return result;
304 +       tmp = leBPL_to_cpup(p);
305 +found_first:
306 +       tmp &= ~0UL >> (BITS_PER_LONG-size);
307 +found_middle:
308 +       return result + ffz(~tmp);
309 +}
310 +
311 +#define find_first_one_bit(addr, size)\
312 +       find_next_one_bit((addr), (size), 0)
313 +
314 +static int read_block_bitmap(struct super_block * sb,
315 +       struct udf_bitmap *bitmap, unsigned int block, unsigned long bitmap_nr)
316 +{
317 +       struct buffer_head *bh = NULL;
318 +       int retval = 0;
319 +       lb_addr loc;
320 +
321 +       loc.logicalBlockNum = bitmap->s_extPosition;
322 +       loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
323 +
324 +       bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block), sb->s_blocksize);
325 +       if (!bh)
326 +       {
327 +               retval = -EIO;
328 +       }
329 +       bitmap->s_block_bitmap[bitmap_nr] = bh;
330 +       return retval;
331 +}
332 +
333 +static int __load_block_bitmap(struct super_block * sb,
334 +       struct udf_bitmap *bitmap, unsigned int block_group)
335 +{
336 +       int retval = 0;
337 +       int nr_groups = bitmap->s_nr_groups;
338 +
339 +       if (block_group >= nr_groups)
340 +       {
341 +               udf_debug("block_group (%d) > nr_groups (%d)\n", block_group, nr_groups);
342 +       }
343 +
344 +       if (bitmap->s_block_bitmap[block_group])
345 +               return block_group;
346 +       else
347 +       {
348 +               retval = read_block_bitmap(sb, bitmap, block_group, block_group);
349 +               if (retval < 0)
350 +                       return retval;
351 +               return block_group;
352 +       }
353 +}
354 +
355 +static inline int load_block_bitmap(struct super_block *sb,
356 +       struct udf_bitmap *bitmap, unsigned int block_group)
357 +{
358 +       int slot;
359 +
360 +       if (bitmap->s_block_bitmap[block_group])
361 +               return 0;
362 +       else
363 +               slot = __load_block_bitmap(sb, bitmap, block_group);
364 +
365 +       if (slot < 0)
366 +               return slot;
367 +
368 +       if (!bitmap->s_block_bitmap[slot])
369 +               return -EIO;
370 +
371 +       return slot;
372 +}
373 +
374 +static void udf_bitmap_free_blocks(const struct inode * inode,
375 +       struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
376 +{
377 +       struct buffer_head * bh = NULL;
378 +       unsigned long block;
379 +       unsigned long block_group;
380 +       unsigned long bit;
381 +       unsigned long i;
382 +       int bitmap_nr;
383 +       unsigned long overflow;
384 +       struct super_block * sb;
385 +
386 +       sb = inode->i_sb;
387 +       if (!sb)
388 +       {
389 +               udf_debug("nonexistent device");
390 +               return;
391 +       }
392 +
393 +       lock_super(sb);
394 +       if (bloc.logicalBlockNum < 0 ||
395 +               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
396 +       {
397 +               udf_debug("%d < %d || %d + %d > %d\n",
398 +                       bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
399 +                       UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
400 +               goto error_return;
401 +       }
402 +
403 +       block = bloc.logicalBlockNum + offset + (sizeof(struct SpaceBitmapDesc) << 3);
404 +
405 +do_more:
406 +       overflow = 0;
407 +       block_group = block >> (sb->s_blocksize_bits + 3);
408 +       bit = block % (sb->s_blocksize << 3);
409 +
410 +       /*
411 +        * Check to see if we are freeing blocks across a group boundary.
412 +        */
413 +       if (bit + count > (sb->s_blocksize << 3))
414 +       {
415 +               overflow = bit + count - (sb->s_blocksize << 3);
416 +               count -= overflow;
417 +       }
418 +       bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
419 +       if (bitmap_nr < 0)
420 +               goto error_return;
421 +
422 +       bh = bitmap->s_block_bitmap[bitmap_nr];
423 +       for (i=0; i < count; i++)
424 +       {
425 +               if (udf_set_bit(bit + i, bh->b_data))
426 +               {
427 +                       udf_debug("bit %ld already set\n", bit + i);
428 +                       udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]);
429 +               }
430 +               else
431 +               {
432 +                       DQUOT_FREE_BLOCK(sb, inode, 1);
433 +                       if (UDF_SB_LVIDBH(sb))
434 +                       {
435 +                               UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
436 +                                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+1);
437 +                       }
438 +               }
439 +       }
440 +       mark_buffer_dirty(bh, 1);
441 +       if (overflow)
442 +       {
443 +               block += count;
444 +               count = overflow;
445 +               goto do_more;
446 +       }
447 +error_return:
448 +       sb->s_dirt = 1;
449 +       if (UDF_SB_LVIDBH(sb))
450 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
451 +       unlock_super(sb);
452 +       return;
453 +}
454 +
455 +static int udf_bitmap_prealloc_blocks(const struct inode * inode,
456 +       struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
457 +       Uint32 block_count)
458 +{
459 +       int alloc_count = 0;
460 +       int bit, block, block_group, group_start;
461 +       int nr_groups, bitmap_nr;
462 +       struct buffer_head *bh;
463 +       struct super_block *sb;
464 +
465 +       sb = inode->i_sb;
466 +       if (!sb)
467 +       {
468 +               udf_debug("nonexistent device\n");
469 +               return 0;
470 +       }
471 +       lock_super(sb);
472 +
473 +       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
474 +               goto out;
475 +
476 +repeat:
477 +       nr_groups = (UDF_SB_PARTLEN(sb, partition) +
478 +               (sizeof(struct SpaceBitmapDesc) << 3) + (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
479 +       block = first_block + (sizeof(struct SpaceBitmapDesc) << 3);
480 +       block_group = block >> (sb->s_blocksize_bits + 3);
481 +       group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
482 +
483 +       bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
484 +       if (bitmap_nr < 0)
485 +               goto out;
486 +       bh = bitmap->s_block_bitmap[bitmap_nr];
487 +
488 +       bit = block % (sb->s_blocksize << 3);
489 +
490 +       while (bit < (sb->s_blocksize << 3) && block_count > 0)
491 +       {
492 +               if (!udf_test_bit(bit, bh->b_data))
493 +                       goto out;
494 +               else if (DQUOT_PREALLOC_BLOCK(sb, inode, 1))
495 +                       goto out;
496 +               else if (!udf_clear_bit(bit, bh->b_data))
497 +               {
498 +                       udf_debug("bit already cleared for block %d\n", bit);
499 +                       DQUOT_FREE_BLOCK(sb, inode, 1);
500 +                       goto out;
501 +               }
502 +               block_count --;
503 +               alloc_count ++;
504 +               bit ++;
505 +               block ++;
506 +       }
507 +       mark_buffer_dirty(bh, 1);
508 +       if (block_count > 0)
509 +               goto repeat;
510 +out:
511 +       if (UDF_SB_LVIDBH(sb))
512 +       {
513 +               UDF_SB_LVID(sb)->freeSpaceTable[partition] =
514 +                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
515 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
516 +       }
517 +       sb->s_dirt = 1;
518 +       unlock_super(sb);
519 +       return alloc_count;
520 +}
521 +
522 +static int udf_bitmap_new_block(const struct inode * inode,
523 +       struct udf_bitmap *bitmap,Uint16 partition, Uint32 goal, int *err)
524 +{
525 +       int tmp, newbit, bit=0, block, block_group, group_start;
526 +       int end_goal, nr_groups, bitmap_nr, i;
527 +       struct buffer_head *bh = NULL;
528 +       struct super_block *sb;
529 +       char *ptr;
530 +       int newblock = 0;
531 +
532 +       *err = -ENOSPC;
533 +       sb = inode->i_sb;
534 +       if (!sb)
535 +       {
536 +               udf_debug("nonexistent device\n");
537 +               return newblock;
538 +       }
539 +       lock_super(sb);
540 +
541 +repeat:
542 +       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
543 +               goal = 0;
544 +
545 +       nr_groups = bitmap->s_nr_groups;
546 +       block = goal + (sizeof(struct SpaceBitmapDesc) << 3);
547 +       block_group = block >> (sb->s_blocksize_bits + 3);
548 +       group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
549 +
550 +       bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
551 +       if (bitmap_nr < 0)
552 +               goto error_return;
553 +       bh = bitmap->s_block_bitmap[bitmap_nr];
554 +       ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
555 +
556 +       if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize)
557 +       {
558 +               bit = block % (sb->s_blocksize << 3);
559 +
560 +               if (udf_test_bit(bit, bh->b_data))
561 +               {
562 +                       goto got_block;
563 +               }
564 +               end_goal = (bit + 63) & ~63;
565 +               bit = udf_find_next_one_bit(bh->b_data, end_goal, bit);
566 +               if (bit < end_goal)
567 +                       goto got_block;
568 +               ptr = memscan((char *)bh->b_data + (bit >> 3), 0xFF, sb->s_blocksize - ((bit + 7) >> 3));
569 +               newbit = (ptr - ((char *)bh->b_data)) << 3;
570 +               if (newbit < sb->s_blocksize << 3)
571 +               {
572 +                       bit = newbit;
573 +                       goto search_back;
574 +               }
575 +               newbit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, bit);
576 +               if (newbit < sb->s_blocksize << 3)
577 +               {
578 +                       bit = newbit;
579 +                       goto got_block;
580 +               }
581 +       }
582 +
583 +       for (i=0; i<(nr_groups*2); i++)
584 +       {
585 +               block_group ++;
586 +               if (block_group >= nr_groups)
587 +                       block_group = 0;
588 +               group_start = block_group ? 0 : sizeof(struct SpaceBitmapDesc);
589 +
590 +               bitmap_nr = load_block_bitmap(sb,bitmap,  block_group);
591 +               if (bitmap_nr < 0)
592 +                       goto error_return;
593 +               bh = bitmap->s_block_bitmap[bitmap_nr];
594 +               if (i < nr_groups)
595 +               {
596 +                       ptr = memscan((char *)bh->b_data + group_start, 0xFF, sb->s_blocksize - group_start);
597 +                       if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize)
598 +                       {
599 +                               bit = (ptr - ((char *)bh->b_data)) << 3;
600 +                               break;
601 +                       }
602 +               }
603 +               else
604 +               {
605 +                       bit = udf_find_next_one_bit((char *)bh->b_data, sb->s_blocksize << 3, group_start << 3);
606 +                       if (bit < sb->s_blocksize << 3)
607 +                               break;
608 +               }
609 +       }
610 +       if (i >= (nr_groups*2))
611 +       {
612 +               unlock_super(sb);
613 +               return newblock;
614 +       }
615 +       if (bit < sb->s_blocksize << 3)
616 +               goto search_back;
617 +       else
618 +               bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3);
619 +       if (bit >= sb->s_blocksize << 3)
620 +       {
621 +               unlock_super(sb);
622 +               return 0;
623 +       }
624 +
625 +search_back:
626 +       for (i=0; i<7 && bit > (group_start << 3) && udf_test_bit(bit - 1, bh->b_data); i++, bit--);
627 +
628 +got_block:
629 +
630 +       /*
631 +        * Check quota for allocation of this block.
632 +        */
633 +       if (DQUOT_ALLOC_BLOCK(sb, inode, 1))
634 +       {
635 +               unlock_super(sb);
636 +               *err = -EDQUOT;
637 +               return 0;
638 +       }
639 +
640 +       newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
641 +               (sizeof(struct SpaceBitmapDesc) << 3);
642 +
643 +       tmp = udf_get_pblock(sb, newblock, partition, 0);
644 +       if (!udf_clear_bit(bit, bh->b_data))
645 +       {
646 +               udf_debug("bit already cleared for block %d\n", bit);
647 +               goto repeat;
648 +       }
649 +
650 +       mark_buffer_dirty(bh, 1);
651 +       if (!(bh = getblk(sb->s_dev, tmp, sb->s_blocksize)))
652 +       {
653 +               udf_debug("cannot get block %d\n", tmp);
654 +               unlock_super(sb);
655 +               return 0;
656 +       }
657 +       memset(bh->b_data, 0, sb->s_blocksize);
658 +       mark_buffer_uptodate(bh, 1);
659 +       mark_buffer_dirty(bh, 1);
660 +       udf_release_data(bh);
661 +
662 +       if (UDF_SB_LVIDBH(sb))
663 +       {
664 +               UDF_SB_LVID(sb)->freeSpaceTable[partition] =
665 +                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1);
666 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
667 +       }
668 +       sb->s_dirt = 1;
669 +       unlock_super(sb);
670 +       *err = 0;
671 +       return newblock;
672 +
673 +error_return:
674 +       *err = -EIO;
675 +       unlock_super(sb);
676 +       return 0;
677 +}
678 +
679 +static void udf_table_free_blocks(const struct inode * inode,
680 +       struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
681 +{
682 +       struct super_block * sb;
683 +       Uint32 start, end;
684 +       Uint32 nextoffset, oextoffset, elen;
685 +       lb_addr nbloc, obloc, eloc;
686 +       struct buffer_head *obh, *nbh;
687 +       char etype;
688 +       int i;
689 +
690 +       udf_debug("ino=%ld, bloc=%d, offset=%d, count=%d\n",
691 +               inode->i_ino, bloc.logicalBlockNum, offset, count);
692 +
693 +       sb = inode->i_sb;
694 +       if (!sb)
695 +       {
696 +               udf_debug("nonexistent device");
697 +               return;
698 +       }
699 +
700 +       if (table == NULL)
701 +               return;
702 +
703 +       lock_super(sb);
704 +       if (bloc.logicalBlockNum < 0 ||
705 +               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
706 +       {
707 +               udf_debug("%d < %d || %d + %d > %d\n",
708 +                       bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
709 +                       UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
710 +               goto error_return;
711 +       }
712 +
713 +       /* We do this up front - There are some error conditions that could occure,
714 +          but.. oh well */
715 +       DQUOT_FREE_BLOCK(sb, inode, count);
716 +       if (UDF_SB_LVIDBH(sb))
717 +       {
718 +               UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
719 +                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)])+count);
720 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
721 +       }
722 +
723 +       start = bloc.logicalBlockNum + offset;
724 +       end = bloc.logicalBlockNum + offset + count - 1;
725 +
726 +       oextoffset = nextoffset = sizeof(struct UnallocatedSpaceEntry);
727 +       elen = 0;
728 +       obloc = nbloc = UDF_I_LOCATION(table);
729 +
730 +       obh = nbh = udf_tread(sb, udf_get_lb_pblock(sb, nbloc, 0), sb->s_blocksize);
731 +       nbh->b_count ++;
732 +
733 +       while (count && (etype =
734 +               udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
735 +       {
736 +               if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
737 +                       start))
738 +               {
739 +                       if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
740 +                       {
741 +                               count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
742 +                               start += ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
743 +                               elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
744 +                       }
745 +                       else
746 +                       {
747 +                               elen = (etype << 30) |
748 +                                       (elen + (count << sb->s_blocksize_bits));
749 +                               start += count;
750 +                               count = 0;
751 +                       }
752 +                       udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
753 +               }
754 +               else if (eloc.logicalBlockNum == (end + 1))
755 +               {
756 +                       if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits))
757 +                       {
758 +                               count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
759 +                               end -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
760 +                               eloc.logicalBlockNum -=
761 +                                       ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
762 +                               elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
763 +                       }
764 +                       else
765 +                       {
766 +                               eloc.logicalBlockNum = start;
767 +                               elen = (etype << 30) |
768 +                                       (elen + (count << sb->s_blocksize_bits));
769 +                               end -= count;
770 +                               count = 0;
771 +                       }
772 +                       udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
773 +               }
774 +
775 +               if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
776 +               {
777 +                       i = -1;
778 +                       obloc = nbloc;
779 +                       udf_release_data(obh);
780 +                       nbh->b_count ++;
781 +                       obh = nbh;
782 +                       oextoffset = 0;
783 +               }
784 +               else
785 +                       oextoffset = nextoffset;
786 +       }
787 +
788 +       if (count)
789 +       {
790 +               /* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
791 +                                a new block, and since we hold the super block lock already
792 +                                very bad things would happen :)
793 +
794 +                                We copy the behavior of udf_add_aext, but instead of
795 +                                trying to allocate a new block close to the existing one,
796 +                                we just steal a block from the extent we are trying to add.
797 +
798 +                                It would be nice if the blocks were close together, but it
799 +                                isn't required.
800 +               */
801 +
802 +               int adsize;
803 +               short_ad *sad = NULL;
804 +               long_ad *lad = NULL;
805 +               struct AllocExtDesc *aed;
806 +
807 +               eloc.logicalBlockNum = start;
808 +               elen = (EXTENT_RECORDED_ALLOCATED << 30) |
809 +                       (count << sb->s_blocksize_bits);
810 +
811 +               if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
812 +                       adsize = sizeof(short_ad);
813 +               else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
814 +                       adsize = sizeof(long_ad);
815 +               else
816 +               {
817 +                       udf_release_data(obh);
818 +                       udf_release_data(nbh);
819 +                       goto error_return;
820 +               }
821 +
822 +               if (nextoffset + (2 * adsize) > sb->s_blocksize)
823 +               {
824 +                       char *sptr, *dptr;
825 +                       int loffset;
826 +       
827 +                       udf_release_data(obh);
828 +                       obh = nbh;
829 +                       obloc = nbloc;
830 +                       oextoffset = nextoffset;
831 +
832 +                       /* Steal a block from the extent being free'd */
833 +                       nbloc.logicalBlockNum = eloc.logicalBlockNum;
834 +                       eloc.logicalBlockNum ++;
835 +                       elen -= sb->s_blocksize;
836 +
837 +                       if (!(nbh = udf_tread(sb,
838 +                               udf_get_lb_pblock(sb, nbloc, 0),
839 +                               sb->s_blocksize)))
840 +                       {
841 +                               udf_release_data(obh);
842 +                               goto error_return;
843 +                       }
844 +                       aed = (struct AllocExtDesc *)(nbh->b_data);
845 +                       aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
846 +                       if (nextoffset + adsize > sb->s_blocksize)
847 +                       {
848 +                               loffset = nextoffset;
849 +                               aed->lengthAllocDescs = cpu_to_le32(adsize);
850 +                               sptr = (obh)->b_data + nextoffset - adsize;
851 +                               dptr = nbh->b_data + sizeof(struct AllocExtDesc);
852 +                               memcpy(dptr, sptr, adsize);
853 +                               nextoffset = sizeof(struct AllocExtDesc) + adsize;
854 +                       }
855 +                       else
856 +                       {
857 +                               loffset = nextoffset + adsize;
858 +                               aed->lengthAllocDescs = cpu_to_le32(0);
859 +                               sptr = (obh)->b_data + nextoffset;
860 +                               nextoffset = sizeof(struct AllocExtDesc);
861 +       
862 +                               if (memcmp(&UDF_I_LOCATION(table), &obloc, sizeof(lb_addr)))
863 +                               {
864 +                                       aed = (struct AllocExtDesc *)(obh)->b_data;
865 +                                       aed->lengthAllocDescs =
866 +                                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
867 +                               }
868 +                               else
869 +                               {
870 +                                       UDF_I_LENALLOC(table) += adsize;
871 +                                       mark_inode_dirty(table);
872 +                               }
873 +                       }
874 +                       udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,
875 +                               nbloc.logicalBlockNum, sizeof(tag));
876 +                       switch (UDF_I_ALLOCTYPE(table))
877 +                       {
878 +                               case ICB_FLAG_AD_SHORT:
879 +                               {
880 +                                       sad = (short_ad *)sptr;
881 +                                       sad->extLength = cpu_to_le32(
882 +                                               EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
883 +                                               sb->s_blocksize);
884 +                                       sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
885 +                                       break;
886 +                               }
887 +                               case ICB_FLAG_AD_LONG:
888 +                               {
889 +                                       lad = (long_ad *)sptr;
890 +                                       lad->extLength = cpu_to_le32(
891 +                                               EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
892 +                                               sb->s_blocksize);
893 +                                       lad->extLocation = cpu_to_lelb(nbloc);
894 +                                       break;
895 +                               }
896 +                       }
897 +                       udf_update_tag(obh->b_data, loffset);
898 +                       mark_buffer_dirty(obh, 1);
899 +               }
900 +
901 +               if (elen) /* It's possible that stealing the block emptied the extent */
902 +               {
903 +                       udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
904 +
905 +                       if (!memcmp(&UDF_I_LOCATION(table), &nbloc, sizeof(lb_addr)))
906 +                       {
907 +                               UDF_I_LENALLOC(table) += adsize;
908 +                               mark_inode_dirty(table);
909 +                       }
910 +                       else
911 +                       {
912 +                               aed = (struct AllocExtDesc *)nbh->b_data;
913 +                               aed->lengthAllocDescs =
914 +                                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
915 +                               udf_update_tag(nbh->b_data, nextoffset);
916 +                               mark_buffer_dirty(nbh, 1);
917 +                       }
918 +               }
919 +       }
920 +
921 +       udf_release_data(nbh);
922 +       udf_release_data(obh);
923 +
924 +error_return:
925 +       sb->s_dirt = 1;
926 +       unlock_super(sb);
927 +       return;
928 +}
929 +
930 +static int udf_table_prealloc_blocks(const struct inode * inode,
931 +       struct inode *table, Uint16 partition, Uint32 first_block,
932 +       Uint32 block_count)
933 +{
934 +       struct super_block *sb;
935 +       int alloc_count = 0;
936 +       Uint32 extoffset, elen, adsize;
937 +       lb_addr bloc, eloc;
938 +       struct buffer_head *bh;
939 +       char etype = -1;
940 +
941 +       udf_debug("ino=%ld, partition=%d, first_block=%d, block_count=%d\n",
942 +               inode->i_ino, partition, first_block, block_count);
943 +
944 +       sb = inode->i_sb;
945 +       if (!sb)
946 +       {
947 +               udf_debug("nonexistent device\n");
948 +               return 0;
949 +       }
950 +
951 +       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
952 +               return 0;
953 +
954 +       if (table == NULL)
955 +               return 0;
956 +
957 +       if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
958 +               adsize = sizeof(short_ad);
959 +       else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
960 +               adsize = sizeof(long_ad);
961 +       else
962 +               return 0;
963 +
964 +       lock_super(sb);
965 +
966 +       extoffset = sizeof(struct UnallocatedSpaceEntry);
967 +       bloc = UDF_I_LOCATION(table);
968 +
969 +       bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize);
970 +       eloc.logicalBlockNum = 0xFFFFFFFF;
971 +
972 +       while (first_block != eloc.logicalBlockNum && (etype =
973 +               udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
974 +       {
975 +               udf_debug("eloc=%d, elen=%d, first_block=%d\n",
976 +                       eloc.logicalBlockNum, elen, first_block);
977 +               ; /* empty loop body */
978 +       }
979 +
980 +       if (first_block == eloc.logicalBlockNum)
981 +       {
982 +               extoffset -= adsize;
983 +
984 +               alloc_count = (elen >> sb->s_blocksize_bits);
985 +               if (alloc_count > block_count)
986 +               {
987 +                       alloc_count = block_count;
988 +                       eloc.logicalBlockNum += alloc_count;
989 +                       elen -= (alloc_count << sb->s_blocksize_bits);
990 +                       udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1);
991 +               }
992 +               else
993 +                       udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh);
994 +       }
995 +       else
996 +               alloc_count = 0;
997 +
998 +       udf_release_data(bh);
999 +
1000 +       if (alloc_count && UDF_SB_LVIDBH(sb))
1001 +       {
1002 +               UDF_SB_LVID(sb)->freeSpaceTable[partition] =
1003 +                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-alloc_count);
1004 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
1005 +       }
1006 +       sb->s_dirt = 1;
1007 +       unlock_super(sb);
1008 +       udf_debug("alloc_count=%d\n", alloc_count);
1009 +       return alloc_count;
1010 +}
1011 +
1012 +static int udf_table_new_block(const struct inode * inode,
1013 +       struct inode *table, Uint16 partition, Uint32 goal, int *err)
1014 +{
1015 +       struct super_block *sb;
1016 +       Uint32 spread = 0xFFFFFFFF, nspread;
1017 +       Uint32 newblock = 0, tmp, adsize;
1018 +       Uint32 extoffset, goal_extoffset, elen, goal_elen = 0;
1019 +       lb_addr bloc, goal_bloc, eloc, goal_eloc;
1020 +       struct buffer_head *bh, *goal_bh;
1021 +       char etype;
1022 +
1023 +       udf_debug("ino=%ld, partition=%d, goal=%d\n",
1024 +               inode->i_ino, partition, goal);
1025 +
1026 +       *err = -ENOSPC;
1027 +       sb = inode->i_sb;
1028 +       if (!sb)
1029 +       {
1030 +               udf_debug("nonexistent device\n");
1031 +               return newblock;
1032 +       }
1033 +
1034 +       if (table == NULL)
1035 +               return newblock;
1036 +
1037 +       if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_SHORT)
1038 +               adsize = sizeof(short_ad);
1039 +       else if (UDF_I_ALLOCTYPE(table) == ICB_FLAG_AD_LONG)
1040 +               adsize = sizeof(long_ad);
1041 +       else
1042 +               return newblock;
1043 +
1044 +       lock_super(sb);
1045 +
1046 +       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
1047 +               goal = 0;
1048 +
1049 +       /* We search for the closest matching block to goal. If we find a exact hit,       we stop. Otherwise we keep going till we run out of extents.
1050 +          We store the buffer_head, bloc, and extoffset of the current closest
1051 +          match and use that when we are done.
1052 +       */
1053 +
1054 +       extoffset = sizeof(struct UnallocatedSpaceEntry);
1055 +       bloc = UDF_I_LOCATION(table);
1056 +
1057 +       goal_bh = bh = udf_tread(sb, udf_get_lb_pblock(sb, bloc, 0), sb->s_blocksize);
1058 +       goal_bh->b_count ++;
1059 +
1060 +       while (spread && (etype =
1061 +               udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
1062 +       {
1063 +               if (goal >= eloc.logicalBlockNum)
1064 +               {
1065 +                       if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits))
1066 +                               nspread = 0;
1067 +                       else
1068 +                               nspread = goal - eloc.logicalBlockNum -
1069 +                                       (elen >> sb->s_blocksize_bits);
1070 +               }
1071 +               else
1072 +                       nspread = eloc.logicalBlockNum - goal;
1073 +
1074 +               if (nspread < spread)
1075 +               {
1076 +                       spread = nspread;
1077 +                       if (goal_bh != bh)
1078 +                       {
1079 +                               udf_release_data(goal_bh);
1080 +                               goal_bh = bh;
1081 +                               goal_bh->b_count ++;
1082 +                       }
1083 +                       goal_bloc = bloc;
1084 +                       goal_extoffset = extoffset - adsize;
1085 +                       goal_eloc = eloc;
1086 +                       goal_elen = (etype << 30) | elen;
1087 +               }
1088 +       }
1089 +
1090 +       udf_release_data(bh);
1091 +
1092 +       if (spread == 0xFFFFFFFF)
1093 +       {
1094 +               udf_release_data(goal_bh);
1095 +               unlock_super(sb);
1096 +               return 0;
1097 +       }
1098 +
1099 +       /* Only allocate blocks from the beginning of the extent.
1100 +          That way, we only delete (empty) extents, never have to insert an
1101 +          extent because of splitting */
1102 +       /* This works, but very poorly.... */
1103 +
1104 +       newblock = goal_eloc.logicalBlockNum;
1105 +       goal_eloc.logicalBlockNum ++;
1106 +       goal_elen -= sb->s_blocksize;
1107 +
1108 +       tmp = udf_get_pblock(sb, newblock, partition, 0);
1109 +       if (!(bh = getblk(sb->s_dev, tmp, sb->s_blocksize)))
1110 +       {
1111 +               udf_debug("cannot get block %d\n", tmp);
1112 +               udf_release_data(bh);
1113 +               unlock_super(sb);
1114 +               return 0;
1115 +       }
1116 +       memset(bh->b_data, 0, sb->s_blocksize);
1117 +       mark_buffer_uptodate(bh, 1);
1118 +       mark_buffer_dirty(bh, 1);
1119 +       udf_release_data(bh);
1120 +
1121 +       if (goal_elen)
1122 +               udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
1123 +       else
1124 +               udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh);
1125 +       udf_release_data(goal_bh);
1126 +
1127 +       if (UDF_SB_LVIDBH(sb))
1128 +       {
1129 +               UDF_SB_LVID(sb)->freeSpaceTable[partition] =
1130 +                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition])-1);
1131 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
1132 +       }
1133 +
1134 +       sb->s_dirt = 1;
1135 +       unlock_super(sb);
1136 +       *err = 0;
1137 +       return newblock;
1138 +}
1139 +
1140 +inline void udf_free_blocks(const struct inode * inode, lb_addr bloc,
1141 +       Uint32 offset, Uint32 count)
1142 +{
1143 +       if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
1144 +       {
1145 +               return udf_bitmap_free_blocks(inode,
1146 +                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_bitmap,
1147 +                       bloc, offset, count);
1148 +       }
1149 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_TABLE)
1150 +       {
1151 +               return udf_table_free_blocks(inode,
1152 +                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_uspace.s_table,
1153 +                       bloc, offset, count);
1154 +       }
1155 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_BITMAP)
1156 +       {
1157 +               return udf_bitmap_free_blocks(inode,
1158 +                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_bitmap,
1159 +                       bloc, offset, count);
1160 +       }
1161 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_FREED_TABLE)
1162 +       {
1163 +               return udf_table_free_blocks(inode,
1164 +                       UDF_SB_PARTMAPS(inode->i_sb)[bloc.partitionReferenceNum].s_fspace.s_table,
1165 +                       bloc, offset, count);
1166 +       }
1167 +       else
1168 +               return;
1169 +}
1170 +
1171 +inline int udf_prealloc_blocks(const struct inode * inode, Uint16 partition,
1172 +       Uint32 first_block, Uint32 block_count)
1173 +{
1174 +       if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
1175 +       {
1176 +               return udf_bitmap_prealloc_blocks(inode,
1177 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
1178 +                       partition, first_block, block_count);
1179 +       }
1180 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
1181 +       {
1182 +               return udf_table_prealloc_blocks(inode,
1183 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
1184 +                       partition, first_block, block_count);
1185 +       }
1186 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
1187 +       {
1188 +               return udf_bitmap_prealloc_blocks(inode,
1189 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
1190 +                       partition, first_block, block_count);
1191 +       }
1192 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
1193 +       {
1194 +               return udf_table_prealloc_blocks(inode,
1195 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
1196 +                       partition, first_block, block_count);
1197 +       }
1198 +       else
1199 +               return 0;
1200 +}
1201 +
1202 +inline int udf_new_block(const struct inode * inode, Uint16 partition,
1203 +       Uint32 goal, int *err)
1204 +{
1205 +       if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
1206 +       {
1207 +               return udf_bitmap_new_block(inode,
1208 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_bitmap,
1209 +                       partition, goal, err);
1210 +       }
1211 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
1212 +       {
1213 +               return udf_table_new_block(inode,
1214 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_uspace.s_table,
1215 +                       partition, goal, err);
1216 +       }
1217 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_BITMAP)
1218 +       {
1219 +               return udf_bitmap_new_block(inode,
1220 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_bitmap,
1221 +                       partition, goal, err);
1222 +       }
1223 +       else if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_FREED_TABLE)
1224 +       {
1225 +               return udf_table_new_block(inode,
1226 +                       UDF_SB_PARTMAPS(inode->i_sb)[partition].s_fspace.s_table,
1227 +                       partition, goal, err);
1228 +       }
1229 +       else
1230 +       {
1231 +               *err = -EIO;
1232 +               return 0;
1233 +       }
1234 +}
1235 diff -Nru linux/fs/udf/crc.c linux.new/fs/udf/crc.c
1236 --- linux/fs/udf/crc.c  Thu Jan  1 01:00:00 1970
1237 +++ linux.new/fs/udf/crc.c      Fri Sep  7 11:32:16 2001
1238 @@ -0,0 +1,178 @@
1239 +/*
1240 + * crc.c
1241 + *
1242 + * PURPOSE
1243 + *     Routines to generate, calculate, and test a 16-bit CRC.
1244 + *
1245 + * DESCRIPTION
1246 + *     The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories
1247 + *     and Ned W. Rhodes of Software Systems Group. It has been published in
1248 + *     "Design and Validation of Computer Protocols", Prentice Hall,
1249 + *     Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4.
1250 + *
1251 + *     Copyright is held by AT&T.
1252 + *
1253 + *     AT&T gives permission for the free use of the CRC source code.
1254 + *
1255 + * CONTACTS
1256 + *     E-mail regarding any portion of the Linux UDF file system should be
1257 + *     directed to the development team mailing list (run by majordomo):
1258 + *             linux_udf@hootie.lvld.hp.com
1259 + *
1260 + * COPYRIGHT
1261 + *     This file is distributed under the terms of the GNU General Public
1262 + *     License (GPL). Copies of the GPL can be obtained from:
1263 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
1264 + *     Each contributing author retains all rights to their own work.
1265 + */
1266 +
1267 +#include "udfdecl.h"
1268 +
1269 +static Uint16 crc_table[256] = {
1270 +       0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U,
1271 +       0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU,
1272 +       0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U,
1273 +       0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU,
1274 +       0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U,
1275 +       0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU,
1276 +       0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U,
1277 +       0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU,
1278 +       0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
1279 +       0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU,
1280 +       0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U,
1281 +       0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU,
1282 +       0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U,
1283 +       0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U,
1284 +       0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U,
1285 +       0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U,
1286 +       0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU,
1287 +       0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
1288 +       0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU,
1289 +       0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
1290 +       0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU,
1291 +       0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
1292 +       0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU,
1293 +       0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
1294 +       0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU,
1295 +       0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U,
1296 +       0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU,
1297 +       0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U,
1298 +       0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U,
1299 +       0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U,
1300 +       0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U,
1301 +       0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U
1302 +};
1303 +
1304 +/*
1305 + * udf_crc
1306 + *
1307 + * PURPOSE
1308 + *     Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial.
1309 + *
1310 + * DESCRIPTION
1311 + *     The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory.
1312 + *     The polynomial used is: x^16 + x^12 + x^15 + 1
1313 + *
1314 + * PRE-CONDITIONS
1315 + *     data            Pointer to the data block.
1316 + *     size            Size of the data block.
1317 + *
1318 + * POST-CONDITIONS
1319 + *     <return>        CRC of the data block.
1320 + *
1321 + * HISTORY
1322 + *     July 21, 1997 - Andrew E. Mileski
1323 + *     Adapted from OSTA-UDF(tm) 1.50 standard.
1324 + */
1325 +extern Uint16
1326 +udf_crc(Uint8 *data, Uint32 size, Uint16 crc)
1327 +{
1328 +       while (size--)
1329 +               crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);
1330 +
1331 +       return crc;
1332 +}
1333 +
1334 +/****************************************************************************/
1335 +#if defined(TEST)
1336 +
1337 +/*
1338 + * PURPOSE
1339 + *     Test udf_crc()
1340 + *
1341 + * HISTORY
1342 + *     July 21, 1997 - Andrew E. Mileski
1343 + *     Adapted from OSTA-UDF(tm) 1.50 standard.
1344 + */
1345 +
1346 +unsigned char bytes[] = { 0x70U, 0x6AU, 0x77U };
1347 +
1348 +int main(void)
1349 +{
1350 +       unsigned short x;
1351 +
1352 +       x = udf_crc16(bytes, sizeof bytes);
1353 +       printf("udf_crc16: calculated = %4.4x, correct = %4.4x\n", x, 0x3299U);
1354 +
1355 +       return 0;
1356 +}
1357 +
1358 +#endif /* defined(TEST) */
1359 +
1360 +/****************************************************************************/
1361 +#if defined(GENERATE)
1362 +
1363 +/*
1364 + * PURPOSE
1365 + *     Generate a table for fast 16-bit CRC calculations (any polynomial).
1366 + *
1367 + * DESCRIPTION
1368 + *     The ITU-T V.41 polynomial is 010041.
1369 + *
1370 + * HISTORY
1371 + *     July 21, 1997 - Andrew E. Mileski
1372 + *     Adapted from OSTA-UDF(tm) 1.50 standard.
1373 + */
1374 +
1375 +#include <stdio.h>
1376 +
1377 +int main(int argc, char **argv)
1378 +{
1379 +       unsigned long crc, poly;
1380 +       int n, i;
1381 +
1382 +       /* Get the polynomial */
1383 +       sscanf(argv[1], "%lo", &poly);
1384 +       if (poly & 0xffff0000U){
1385 +               fprintf(stderr, "polynomial is too large\en");
1386 +               exit(1);
1387 +       }
1388 +
1389 +       printf("/* CRC 0%o */\n", poly);
1390 +
1391 +       /* Create a table */
1392 +       printf("static unsigned short crc_table[256] = {\n");
1393 +       for (n = 0; n < 256; n++){
1394 +               if (n % 8 == 0)
1395 +                       printf("\t");
1396 +               crc = n << 8;
1397 +               for (i = 0; i < 8; i++){
1398 +                       if(crc & 0x8000U)
1399 +                               crc = (crc << 1) ^ poly;
1400 +                       else
1401 +                               crc <<= 1;
1402 +               crc &= 0xFFFFU;
1403 +               }
1404 +               if (n == 255)
1405 +                       printf("0x%04xU ", crc);
1406 +               else
1407 +                       printf("0x%04xU, ", crc);
1408 +               if(n % 8 == 7)
1409 +                       printf("\n");
1410 +       }
1411 +       printf("};\n");
1412 +
1413 +       return 0;
1414 +}
1415 +
1416 +#endif /* defined(GENERATE) */
1417 diff -Nru linux/fs/udf/dir.c linux.new/fs/udf/dir.c
1418 --- linux/fs/udf/dir.c  Thu Jan  1 01:00:00 1970
1419 +++ linux.new/fs/udf/dir.c      Fri Sep  7 11:32:16 2001
1420 @@ -0,0 +1,283 @@
1421 +/*
1422 + * dir.c
1423 + *
1424 + * PURPOSE
1425 + *  Directory handling routines for the OSTA-UDF(tm) filesystem.
1426 + *
1427 + * CONTACTS
1428 + *     E-mail regarding any portion of the Linux UDF file system should be
1429 + *     directed to the development team mailing list (run by majordomo):
1430 + *             linux_udf@hootie.lvld.hp.com
1431 + *
1432 + * COPYRIGHT
1433 + *     This file is distributed under the terms of the GNU General Public
1434 + *     License (GPL). Copies of the GPL can be obtained from:
1435 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
1436 + *     Each contributing author retains all rights to their own work.
1437 + *
1438 + *  (C) 1998-2000 Ben Fennema
1439 + *
1440 + * HISTORY
1441 + *
1442 + *  10/05/98 dgb  Split directory operations into it's own file
1443 + *                Implemented directory reads via do_udf_readdir
1444 + *  10/06/98      Made directory operations work!
1445 + *  11/17/98      Rewrote directory to support ICB_FLAG_AD_LONG
1446 + *  11/25/98 blf  Rewrote directory handling (readdir+lookup) to support reading
1447 + *                across blocks.
1448 + *  12/12/98      Split out the lookup code to namei.c. bulk of directory
1449 + *                code now in directory.c:udf_fileident_read.
1450 + */
1451 +
1452 +#include "udfdecl.h"
1453 +
1454 +#if defined(__linux__) && defined(__KERNEL__)
1455 +#include <linux/version.h>
1456 +#include "udf_i.h"
1457 +#include "udf_sb.h"
1458 +#include <linux/string.h>
1459 +#include <linux/errno.h>
1460 +#include <linux/mm.h>
1461 +#include <linux/malloc.h>
1462 +#include <linux/udf_fs.h>
1463 +#endif
1464 +
1465 +/* Prototypes for file operations */
1466 +static int udf_readdir(struct file *, void *, filldir_t);
1467 +static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *);
1468 +
1469 +/* readdir and lookup functions */
1470 +
1471 +static struct file_operations udf_dir_operations = {
1472 +       NULL,                   /* lllseek */
1473 +       NULL,                   /* read */
1474 +       NULL,                   /* write */
1475 +       udf_readdir,    /* readdir */
1476 +       NULL,                   /* poll */
1477 +       udf_ioctl,              /* ioctl */
1478 +       NULL,                   /* mmap */
1479 +       NULL,                   /* open */
1480 +       NULL,                   /* flush */
1481 +       NULL,                   /* release */
1482 +       udf_sync_file,  /* fsync */
1483 +       NULL,                   /* fasync */
1484 +       NULL,                   /* check_media_change */
1485 +       NULL,                   /* revalidate */
1486 +       NULL                    /* lock */
1487 +};
1488 +
1489 +struct inode_operations udf_dir_inode_operations = {
1490 +       &udf_dir_operations,
1491 +       udf_create,     /* create */
1492 +       udf_lookup,             /* lookup */
1493 +       udf_link,               /* link */
1494 +       udf_unlink,             /* unlink */
1495 +       udf_symlink,    /* symlink */
1496 +       udf_mkdir,              /* mkdir */
1497 +       udf_rmdir,              /* rmdir */
1498 +       udf_mknod,              /* mknod */
1499 +       udf_rename,             /* rename */
1500 +       NULL,                   /* readlink */
1501 +       NULL,                   /* follow_link */
1502 +       NULL,                   /* readpage */
1503 +       NULL,                   /* writepage */
1504 +       NULL,                   /* bmap */
1505 +       NULL,                   /* truncate */
1506 +       NULL,                   /* permission */
1507 +       NULL,                   /* smap */
1508 +       NULL,                   /* updatepage */
1509 +       NULL                    /* revalidate */
1510 +};
1511 +
1512 +/*
1513 + * udf_readdir
1514 + *
1515 + * PURPOSE
1516 + *     Read a directory entry.
1517 + *
1518 + * DESCRIPTION
1519 + *     Optional - sys_getdents() will return -ENOTDIR if this routine is not
1520 + *     available.
1521 + *
1522 + *     Refer to sys_getdents() in fs/readdir.c
1523 + *     sys_getdents() -> .
1524 + *
1525 + * PRE-CONDITIONS
1526 + *     filp                    Pointer to directory file.
1527 + *     buf                     Pointer to directory entry buffer.
1528 + *     filldir                 Pointer to filldir function.
1529 + *
1530 + * POST-CONDITIONS
1531 + *     <return>                >=0 on success.
1532 + *
1533 + * HISTORY
1534 + *     July 1, 1997 - Andrew E. Mileski
1535 + *     Written, tested, and released.
1536 + */
1537 +
1538 +int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
1539 +{
1540 +       struct inode *dir = filp->f_dentry->d_inode;
1541 +       int result;
1542 +
1543 +       if (!dir)
1544 +          return -EBADF;
1545 +
1546 +       if (!S_ISDIR(dir->i_mode))
1547 +          return -ENOTDIR;
1548 +
1549 +       if ( filp->f_pos == 0 ) 
1550 +       {
1551 +               if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino))
1552 +                       return 0;
1553 +       }
1554
1555 +       result = do_udf_readdir(dir, filp, filldir, dirent);
1556 +       UPDATE_ATIME(dir);
1557 +       return result;
1558 +}
1559 +
1560 +static int 
1561 +do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *dirent)
1562 +{
1563 +       struct udf_fileident_bh fibh;
1564 +       struct FileIdentDesc *fi=NULL;
1565 +       struct FileIdentDesc cfi;
1566 +       int block, iblock;
1567 +       int nf_pos = filp->f_pos;
1568 +       int flen;
1569 +       char fname[255];
1570 +       char *nameptr;
1571 +       Uint16 liu;
1572 +       Uint8 lfi;
1573 +       int size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
1574 +       struct buffer_head * bh = NULL;
1575 +       lb_addr bloc, eloc;
1576 +       Uint32 extoffset, elen, offset;
1577 +
1578 +       if (nf_pos >= size)
1579 +               return 1;
1580 +
1581 +       if (nf_pos == 0)
1582 +               nf_pos = (udf_ext0_offset(dir) >> 2);
1583 +
1584 +       fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
1585 +       if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
1586 +               &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
1587 +       {
1588 +               block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
1589 +               if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
1590 +               {
1591 +                       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
1592 +                               extoffset -= sizeof(short_ad);
1593 +                       else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
1594 +                               extoffset -= sizeof(long_ad);
1595 +               }
1596 +               else
1597 +                       offset = 0;
1598 +       }
1599 +       else
1600 +       {
1601 +               udf_release_data(bh);
1602 +               return 0;
1603 +       }
1604 +
1605 +       if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
1606 +       {
1607 +               udf_release_data(bh);
1608 +               return 0;
1609 +       }
1610 +
1611 +       while ( nf_pos < size )
1612 +       {
1613 +               filp->f_pos = nf_pos;
1614 +
1615 +               fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
1616 +
1617 +               if (!fi)
1618 +               {
1619 +                       if (fibh.sbh != fibh.ebh)
1620 +                               udf_release_data(fibh.ebh);
1621 +                       udf_release_data(fibh.sbh);
1622 +                       udf_release_data(bh);
1623 +                       return 1;
1624 +               }
1625 +
1626 +               liu = le16_to_cpu(cfi.lengthOfImpUse);
1627 +               lfi = cfi.lengthFileIdent;
1628 +
1629 +               if (fibh.sbh == fibh.ebh)
1630 +                       nameptr = fi->fileIdent + liu;
1631 +               else
1632 +               {
1633 +                       int poffset;    /* Unpaded ending offset */
1634 +
1635 +                       poffset = fibh.soffset + sizeof(struct FileIdentDesc) + liu + lfi;
1636 +
1637 +                       if (poffset >= lfi)
1638 +                               nameptr = (char *)(fibh.ebh->b_data + poffset - lfi);
1639 +                       else
1640 +                       {
1641 +                               nameptr = fname;
1642 +                               memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
1643 +                               memcpy(nameptr + lfi - poffset, fibh.ebh->b_data, poffset);
1644 +                       }
1645 +               }
1646 +
1647 +               if ( (cfi.fileCharacteristics & FILE_DELETED) != 0 )
1648 +               {
1649 +                       if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
1650 +                               continue;
1651 +               }
1652 +               
1653 +               if ( (cfi.fileCharacteristics & FILE_HIDDEN) != 0 )
1654 +               {
1655 +                       if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
1656 +                               continue;
1657 +               }
1658 +
1659 +               iblock = udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0);
1660
1661 +               if (!lfi) /* parent directory */
1662 +               {
1663 +                       if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino))
1664 +                       {
1665 +                               if (fibh.sbh != fibh.ebh)
1666 +                                       udf_release_data(fibh.ebh);
1667 +                               udf_release_data(fibh.sbh);
1668 +                               udf_release_data(bh);
1669 +                               return 1;
1670 +                       }
1671 +               }
1672 +               else
1673 +               {
1674 +                       if ((flen = udf_get_filename(nameptr, fname, lfi)))
1675 +                       {
1676 +                               if (filldir(dirent, fname, flen, filp->f_pos, iblock))
1677 +                               {
1678 +                                       if (fibh.sbh != fibh.ebh)
1679 +                                               udf_release_data(fibh.ebh);
1680 +                                       udf_release_data(fibh.sbh);
1681 +                                       udf_release_data(bh);
1682 +                                       return 1; /* halt enum */
1683 +                               }
1684 +                       }
1685 +                       else
1686 +                       {
1687 +                               udf_debug("size=%d, nf_pos=%d, liu=%d, lfi=%d\n", size, nf_pos, liu, lfi);
1688 +                       }
1689 +               }
1690 +       } /* end while */
1691 +
1692 +       filp->f_pos = nf_pos;
1693 +
1694 +       if (fibh.sbh != fibh.ebh)
1695 +               udf_release_data(fibh.ebh);
1696 +       udf_release_data(fibh.sbh);
1697 +       udf_release_data(bh);
1698 +
1699 +       if ( filp->f_pos >= size)
1700 +               return 1;
1701 +       else
1702 +               return 0;
1703 +}
1704 diff -Nru linux/fs/udf/directory.c linux.new/fs/udf/directory.c
1705 --- linux/fs/udf/directory.c    Thu Jan  1 01:00:00 1970
1706 +++ linux.new/fs/udf/directory.c        Fri Sep  7 11:32:16 2001
1707 @@ -0,0 +1,330 @@
1708 +/*
1709 + * directory.c
1710 + *
1711 + * PURPOSE
1712 + *     Directory related functions
1713 + *
1714 + * CONTACTS
1715 + *     E-mail regarding any portion of the Linux UDF file system should be
1716 + *     directed to the development team mailing list (run by majordomo):
1717 + *             linux_udf@hootie.lvld.hp.com
1718 + *
1719 + * COPYRIGHT
1720 + *     This file is distributed under the terms of the GNU General Public
1721 + *     License (GPL). Copies of the GPL can be obtained from:
1722 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
1723 + *     Each contributing author retains all rights to their own work.
1724 + */
1725 +
1726 +#include "udfdecl.h"
1727 +
1728 +#if defined(__linux__) && defined(__KERNEL__)
1729 +
1730 +#include <linux/fs.h>
1731 +#include <linux/string.h>
1732 +#include <linux/udf_fs.h>
1733 +
1734 +#else
1735 +
1736 +#include <sys/types.h>
1737 +#include <stdio.h>
1738 +#include <unistd.h>
1739 +
1740 +#endif
1741 +
1742 +#ifdef __KERNEL__
1743 +
1744 +Uint8 * udf_filead_read(struct inode *dir, Uint8 *tmpad, Uint8 ad_size,
1745 +       lb_addr fe_loc, int *pos, int *offset, struct buffer_head **bh, int *error)
1746 +{
1747 +       int loffset = *offset;
1748 +       int block;
1749 +       Uint8 *ad;
1750 +       int remainder;
1751 +
1752 +       *error = 0;
1753 +
1754 +       ad = (Uint8 *)(*bh)->b_data + *offset;
1755 +       *offset += ad_size;
1756 +
1757 +       if (!ad)
1758 +       {
1759 +               udf_release_data(*bh);
1760 +               *error = 1;
1761 +               return NULL;
1762 +       }
1763 +
1764 +       if (*offset == dir->i_sb->s_blocksize)
1765 +       {
1766 +               udf_release_data(*bh);
1767 +               block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
1768 +               if (!block)
1769 +                       return NULL;
1770 +               if (!(*bh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
1771 +                       return NULL;
1772 +       }
1773 +       else if (*offset > dir->i_sb->s_blocksize)
1774 +       {
1775 +               ad = tmpad;
1776 +
1777 +               remainder = dir->i_sb->s_blocksize - loffset;
1778 +               memcpy((Uint8 *)ad, (*bh)->b_data + loffset, remainder);
1779 +
1780 +               udf_release_data(*bh);
1781 +               block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
1782 +               if (!block)
1783 +                       return NULL;
1784 +               if (!((*bh) = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
1785 +                       return NULL;
1786 +
1787 +               memcpy((Uint8 *)ad + remainder, (*bh)->b_data, ad_size - remainder);
1788 +               *offset = ad_size - remainder;
1789 +       }
1790 +       return ad;
1791 +}
1792 +
1793 +struct FileIdentDesc *
1794 +udf_fileident_read(struct inode *dir, int *nf_pos,
1795 +       struct udf_fileident_bh *fibh,
1796 +       struct FileIdentDesc *cfi,
1797 +       lb_addr *bloc, Uint32 *extoffset, 
1798 +       lb_addr *eloc, Uint32 *elen,
1799 +       Uint32 *offset, struct buffer_head **bh)
1800 +{
1801 +       struct FileIdentDesc *fi;
1802 +       int block;
1803 +
1804 +       fibh->soffset = fibh->eoffset;
1805 +
1806 +       if (fibh->eoffset == dir->i_sb->s_blocksize)
1807 +       {
1808 +               int lextoffset = *extoffset;
1809 +
1810 +               if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
1811 +                       EXTENT_RECORDED_ALLOCATED)
1812 +               {
1813 +                       return NULL;
1814 +               }
1815 +
1816 +               block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
1817 +
1818 +               (*offset) ++;
1819 +
1820 +               if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
1821 +                       *offset = 0;
1822 +               else
1823 +                       *extoffset = lextoffset;
1824 +
1825 +               udf_release_data(fibh->sbh);
1826 +               if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
1827 +                       return NULL;
1828 +               fibh->soffset = fibh->eoffset = 0;
1829 +       }
1830 +       else if (fibh->sbh != fibh->ebh)
1831 +       {
1832 +               udf_release_data(fibh->sbh);
1833 +               fibh->sbh = fibh->ebh;
1834 +       }
1835 +
1836 +       fi = udf_get_fileident(fibh->sbh->b_data, dir->i_sb->s_blocksize,
1837 +               &(fibh->eoffset));
1838 +
1839 +       if (!fi)
1840 +               return NULL;
1841 +
1842 +       *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
1843 +
1844 +       if (fibh->eoffset <= dir->i_sb->s_blocksize)
1845 +       {
1846 +               memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
1847 +       }
1848 +       else if (fibh->eoffset > dir->i_sb->s_blocksize)
1849 +       {
1850 +               int lextoffset = *extoffset;
1851 +
1852 +               if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
1853 +                       EXTENT_RECORDED_ALLOCATED)
1854 +               {
1855 +                       return NULL;
1856 +               }
1857 +
1858 +               block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
1859 +
1860 +               (*offset) ++;
1861 +
1862 +               if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
1863 +                       *offset = 0;
1864 +               else
1865 +                       *extoffset = lextoffset;
1866 +
1867 +               fibh->soffset -= dir->i_sb->s_blocksize;
1868 +               fibh->eoffset -= dir->i_sb->s_blocksize;
1869 +
1870 +               if (!(fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
1871 +                       return NULL;
1872 +
1873 +               if (sizeof(struct FileIdentDesc) > - fibh->soffset)
1874 +               {
1875 +                       int fi_len;
1876 +
1877 +                       memcpy((Uint8 *)cfi, (Uint8 *)fi, - fibh->soffset);
1878 +                       memcpy((Uint8 *)cfi - fibh->soffset, fibh->ebh->b_data,
1879 +                               sizeof(struct FileIdentDesc) + fibh->soffset);
1880 +
1881 +                       fi_len = (sizeof(struct FileIdentDesc) + cfi->lengthFileIdent +
1882 +                               le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
1883 +
1884 +                       *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
1885 +                       fibh->eoffset = fibh->soffset + fi_len;
1886 +               }
1887 +               else
1888 +               {
1889 +                       memcpy((Uint8 *)cfi, (Uint8 *)fi, sizeof(struct FileIdentDesc));
1890 +               }
1891 +       }
1892 +       return fi;
1893 +}
1894 +#endif
1895 +
1896 +struct FileIdentDesc * 
1897 +udf_get_fileident(void * buffer, int bufsize, int * offset)
1898 +{
1899 +       struct FileIdentDesc *fi;
1900 +       int lengthThisIdent;
1901 +       Uint8 * ptr;
1902 +       int padlen;
1903 +
1904 +       if ( (!buffer) || (!offset) ) {
1905 +#ifdef __KERNEL__
1906 +               udf_debug("invalidparms\n, buffer=%p, offset=%p\n", buffer, offset);
1907 +#endif
1908 +               return NULL;
1909 +       }
1910 +
1911 +       ptr = buffer;
1912 +
1913 +       if ( (*offset > 0) && (*offset < bufsize) ) {
1914 +               ptr += *offset;
1915 +       }
1916 +       fi=(struct FileIdentDesc *)ptr;
1917 +       if (le16_to_cpu(fi->descTag.tagIdent) != TID_FILE_IDENT_DESC)
1918 +       {
1919 +#ifdef __KERNEL__
1920 +               udf_debug("0x%x != TID_FILE_IDENT_DESC\n",
1921 +                       le16_to_cpu(fi->descTag.tagIdent));
1922 +               udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
1923 +                       *offset, (unsigned long)sizeof(struct FileIdentDesc), bufsize);
1924 +#endif
1925 +               return NULL;
1926 +       }
1927 +       if ( (*offset + sizeof(struct FileIdentDesc)) > bufsize )
1928 +       {
1929 +               lengthThisIdent = sizeof(struct FileIdentDesc);
1930 +       }
1931 +       else
1932 +               lengthThisIdent = sizeof(struct FileIdentDesc) +
1933 +                       fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
1934 +
1935 +       /* we need to figure padding, too! */
1936 +       padlen = lengthThisIdent % UDF_NAME_PAD;
1937 +       if (padlen)
1938 +               lengthThisIdent += (UDF_NAME_PAD - padlen);
1939 +       *offset = *offset + lengthThisIdent;
1940 +
1941 +       return fi;
1942 +}
1943 +
1944 +extent_ad *
1945 +udf_get_fileextent(void * buffer, int bufsize, int * offset)
1946 +{
1947 +       extent_ad * ext;
1948 +       struct FileEntry *fe;
1949 +       Uint8 * ptr;
1950 +
1951 +       if ( (!buffer) || (!offset) )
1952 +       {
1953 +#ifdef __KERNEL__
1954 +               printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
1955 +#endif
1956 +               return NULL;
1957 +       }
1958 +
1959 +       fe = (struct FileEntry *)buffer;
1960 +
1961 +       if ( le16_to_cpu(fe->descTag.tagIdent) != TID_FILE_ENTRY )
1962 +       {
1963 +#ifdef __KERNEL__
1964 +               udf_debug("0x%x != TID_FILE_ENTRY\n",
1965 +                       le16_to_cpu(fe->descTag.tagIdent));
1966 +#endif
1967 +               return NULL;
1968 +       }
1969 +
1970 +       ptr=(Uint8 *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
1971 +
1972 +       if ( (*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)) )
1973 +       {
1974 +               ptr += *offset;
1975 +       }
1976 +
1977 +       ext = (extent_ad *)ptr;
1978 +
1979 +       *offset = *offset + sizeof(extent_ad);
1980 +       return ext;
1981 +}
1982 +
1983 +short_ad *
1984 +udf_get_fileshortad(void * buffer, int maxoffset, int *offset, int inc)
1985 +{
1986 +       short_ad * sa;
1987 +       Uint8 * ptr;
1988 +
1989 +       if ( (!buffer) || (!offset) )
1990 +       {
1991 +#ifdef __KERNEL__
1992 +               printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
1993 +#endif
1994 +               return NULL;
1995 +       }
1996 +
1997 +       ptr = (Uint8 *)buffer;
1998 +
1999 +       if ( (*offset > 0) && (*offset < maxoffset) )
2000 +               ptr += *offset;
2001 +       else
2002 +               return NULL;
2003 +
2004 +       if ((sa = (short_ad *)ptr)->extLength == 0)
2005 +               return NULL;
2006 +       else if (inc)
2007 +               (*offset) += sizeof(short_ad);
2008 +       return sa;
2009 +}
2010 +
2011 +long_ad *
2012 +udf_get_filelongad(void * buffer, int maxoffset, int * offset, int inc)
2013 +{
2014 +       long_ad * la;
2015 +       Uint8 * ptr;
2016 +
2017 +       if ( (!buffer) || !(offset) ) 
2018 +       {
2019 +#ifdef __KERNEL__
2020 +               printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
2021 +#endif
2022 +               return NULL;
2023 +       }
2024 +
2025 +       ptr = (Uint8 *)buffer;
2026 +
2027 +       if ( (*offset > 0) && (*offset < maxoffset) )
2028 +               ptr += *offset;
2029 +       else
2030 +               return NULL;
2031 +
2032 +       if ((la = (long_ad *)ptr)->extLength == 0)
2033 +               return NULL;
2034 +       else if (inc)
2035 +               (*offset) += sizeof(long_ad);
2036 +       return la;
2037 +}
2038 diff -Nru linux/fs/udf/file.c linux.new/fs/udf/file.c
2039 --- linux/fs/udf/file.c Thu Jan  1 01:00:00 1970
2040 +++ linux.new/fs/udf/file.c     Fri Sep  7 11:32:16 2001
2041 @@ -0,0 +1,549 @@
2042 +/*
2043 + * file.c
2044 + *
2045 + * PURPOSE
2046 + *  File handling routines for the OSTA-UDF(tm) filesystem.
2047 + *
2048 + * CONTACTS
2049 + *  E-mail regarding any portion of the Linux UDF file system should be
2050 + *  directed to the development team mailing list (run by majordomo):
2051 + *    linux_udf@hootie.lvld.hp.com
2052 + *
2053 + * COPYRIGHT
2054 + *  This file is distributed under the terms of the GNU General Public
2055 + *  License (GPL). Copies of the GPL can be obtained from:
2056 + *    ftp://prep.ai.mit.edu/pub/gnu/GPL
2057 + *  Each contributing author retains all rights to their own work.
2058 + *
2059 + *  (C) 1998-1999 Dave Boynton
2060 + *  (C) 1998-2000 Ben Fennema
2061 + *  (C) 1999-2000 Stelias Computing Inc
2062 + *
2063 + * HISTORY
2064 + *
2065 + *  10/02/98 dgb  Attempt to integrate into udf.o
2066 + *  10/07/98      Switched to using generic_readpage, etc., like isofs
2067 + *                And it works!
2068 + *  12/06/98 blf  Added udf_file_read. uses generic_file_read for all cases but
2069 + *                ICB_FLAG_AD_IN_ICB.
2070 + *  04/06/99      64 bit file handling on 32 bit systems taken from ext2 file.c
2071 + *  05/12/99      Preliminary file write support
2072 + */
2073 +
2074 +#include "udfdecl.h"
2075 +#include <linux/fs.h>
2076 +#include <linux/udf_fs.h>
2077 +#include <asm/uaccess.h>
2078 +#include <linux/kernel.h>
2079 +#include <linux/string.h> /* memset */
2080 +#include <linux/errno.h>
2081 +#include <linux/locks.h>
2082 +
2083 +#include "udf_i.h"
2084 +#include "udf_sb.h"
2085 +
2086 +#define NBUF   32
2087 +
2088 +typedef void * poll_table; 
2089 +
2090 +/*
2091 + * Make sure the offset never goes beyond the 32-bit mark..
2092 + */
2093 +static long long udf_file_llseek(struct file * file, long long offset, int origin)
2094 +{
2095 +       struct inode * inode = file->f_dentry->d_inode;
2096 +
2097 +       switch (origin)
2098 +       {
2099 +               case 2:
2100 +               {
2101 +                       offset += inode->i_size;
2102 +                       break;
2103 +               }
2104 +               case 1:
2105 +               {
2106 +                       offset += file->f_pos;
2107 +                       break;
2108 +               }
2109 +       }
2110 +#if BITS_PER_LONG < 64
2111 +       if (((unsigned long long) offset >> 32) != 0)
2112 +       {
2113 +               return -EINVAL;
2114 +       }
2115 +#endif
2116 +       if (offset != file->f_pos)
2117 +       {
2118 +               file->f_pos = offset;
2119 +               file->f_reada = 0;
2120 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
2121 +               file->f_version = ++event;
2122 +#else
2123 +               file->f_version = ++global_event;
2124 +#endif
2125 +       }
2126 +       return offset;
2127 +}
2128 +
2129 +static inline void remove_suid(struct inode * inode)
2130 +{
2131 +       unsigned int mode;
2132 +
2133 +       /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
2134 +       mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
2135 +
2136 +       /* was any of the uid bits set? */
2137 +       mode &= inode->i_mode;
2138 +       if (mode && !capable(CAP_FSETID))
2139 +       {
2140 +               inode->i_mode &= ~mode;
2141 +               mark_inode_dirty(inode);
2142 +       }
2143 +}
2144 +
2145 +static ssize_t udf_file_write(struct file * filp, const char * buf,
2146 +       size_t count, loff_t *ppos)
2147 +{
2148 +       struct inode * inode = filp->f_dentry->d_inode;
2149 +       off_t pos;
2150 +       long block;
2151 +       int offset;
2152 +       int written, c;
2153 +       struct buffer_head * bh, * bufferlist[NBUF];
2154 +       struct super_block * sb;
2155 +       int err;
2156 +       int i, buffercount, write_error, new_buffer;
2157 +       unsigned long limit;
2158 +
2159 +       /* POSIX: mtime/ctime may not change for 0 count */
2160 +       if (!count)
2161 +               return 0;
2162 +       /* This makes the bounds-checking arithmetic later on much more
2163 +        * sane. */
2164 +       write_error = buffercount = 0;
2165 +       if (!inode)
2166 +       {
2167 +               printk("udf_file_write: inode = NULL\n");
2168 +               return -EINVAL;
2169 +       }
2170 +       sb = inode->i_sb;
2171 +       if (sb->s_flags & MS_RDONLY)
2172 +       {
2173 +               return -ENOSPC;
2174 +       }
2175 +
2176 +       if (!S_ISREG(inode->i_mode))
2177 +       {
2178 +               udf_warning(sb, "udf_file_write", "mode = %07o", inode->i_mode);
2179 +               return -EINVAL;
2180 +       }
2181 +       remove_suid(inode);
2182 +
2183 +       if (filp->f_flags & O_APPEND)
2184 +               pos = inode->i_size;
2185 +       else
2186 +       {
2187 +               pos = *ppos;
2188 +               if (pos != *ppos)
2189 +                       return -EINVAL;
2190 +       }
2191 +
2192 +#if BITS_PER_LONG < 64
2193 +       /* If the fd's pos is already greater than or equal to the file
2194 +        * descriptor's offset maximum, then we need to return EFBIG for
2195 +        * any non-zero count (and we already tested for zero above). */
2196 +       if (((off_t) pos) >= 0x7FFFFFFFUL)
2197 +               return -EFBIG;
2198 +
2199 +       /* If we are about to overflow the maximum file size, we also
2200 +        * need to return the error, but only if no bytes can be written
2201 +        * successfully. */
2202 +       if (((off_t) pos + count) > 0x7FFFFFFFUL)
2203 +       {
2204 +               count = 0x7FFFFFFFL - pos;
2205 +               if (((ssize_t) count) < 0)
2206 +                       return -EFBIG;
2207 +       }
2208 +#endif
2209 +
2210 +       limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
2211 +       if (limit < RLIM_INFINITY)
2212 +       {
2213 +               if (((off_t) pos + count) >= limit)
2214 +               {
2215 +                       count = limit - pos;
2216 +                       if (((ssize_t) count) <= 0)
2217 +                       {
2218 +                               send_sig(SIGXFSZ, current, 0);
2219 +                               return -EFBIG;
2220 +                       }
2221 +               }
2222 +       }
2223 +
2224 +
2225 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
2226 +       {
2227 +               if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
2228 +                       pos + count))
2229 +               {
2230 +                       udf_expand_file_adinicb(inode, pos + count, &err);
2231 +                       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
2232 +                       {
2233 +                               udf_debug("udf_expand_file_adinicb: err=%d\n", err);
2234 +                               return err;
2235 +                       }
2236 +               }
2237 +               else
2238 +               {
2239 +                       if (pos + count > inode->i_size)
2240 +                               UDF_I_LENALLOC(inode) = pos + count;
2241 +                       else
2242 +                               UDF_I_LENALLOC(inode) = inode->i_size;
2243 +                       pos += udf_file_entry_alloc_offset(inode);
2244 +               }
2245 +       }
2246 +
2247 +       if (filp->f_flags & O_SYNC)
2248 +               ; /* Do something */
2249 +       block = pos >> sb->s_blocksize_bits;
2250 +       offset = pos & (sb->s_blocksize - 1);
2251 +       c = sb->s_blocksize - offset;
2252 +       written = 0;
2253 +       do
2254 +       {
2255 +               bh = udf_getblk(inode, block, 1, &err);
2256 +               if (!bh)
2257 +               {
2258 +                       if (!written)
2259 +                               written = err;
2260 +                       break;
2261 +               }
2262 +               if (c > count)
2263 +                       c = count;
2264 +
2265 +               new_buffer = (!buffer_uptodate(bh) && !buffer_locked(bh) &&
2266 +                       c == sb->s_blocksize);
2267 +
2268 +               if (new_buffer)
2269 +               {
2270 +
2271 +                       set_bit(BH_Lock, &bh->b_state);
2272 +                       c -= copy_from_user(bh->b_data + offset, buf, c);
2273 +                       if (c != sb->s_blocksize)
2274 +                       {
2275 +                               c = 0;
2276 +                               unlock_buffer(bh);
2277 +                               brelse(bh);
2278 +                               if (!written)
2279 +                                       written = -EFAULT;
2280 +                               break;
2281 +                       }
2282 +                       mark_buffer_uptodate(bh, 1);
2283 +                       unlock_buffer(bh);
2284 +               }
2285 +               else
2286 +               {
2287 +                       if (!buffer_uptodate(bh))
2288 +                       {
2289 +                               ll_rw_block(READ, 1, &bh);
2290 +                               wait_on_buffer(bh);
2291 +                               if (!buffer_uptodate(bh))
2292 +                               {
2293 +                                       brelse(bh);
2294 +                                       if (!written)
2295 +                                               written = -EIO;
2296 +                                       break;
2297 +                               }
2298 +                       }
2299 +                       c -= copy_from_user(bh->b_data + offset, buf, c);
2300 +               }
2301 +               if (!c)
2302 +               {
2303 +                       brelse(bh);
2304 +                       if (!written)
2305 +                               written = -EFAULT;
2306 +                       break;
2307 +               }
2308 +               mark_buffer_dirty(bh, 0);
2309 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
2310 +               update_vm_cache(inode, pos, bh->b_data + offset, c);
2311 +#else
2312 +               update_vm_cache_conditional(inode, pos, bh->b_data + offset, c,
2313 +                       (unsigned long) buf);
2314 +#endif
2315 +               pos += c;
2316 +               written += c;
2317 +               buf += c;
2318 +               count -= c;
2319 +
2320 +               if (filp->f_flags & O_SYNC)
2321 +                       bufferlist[buffercount++] = bh;
2322 +               else
2323 +                       brelse(bh);
2324 +               if (buffercount == NBUF)
2325 +               {
2326 +                       ll_rw_block(WRITE, buffercount, bufferlist);
2327 +                       for (i=0; i<buffercount; i++)
2328 +                       {
2329 +                               wait_on_buffer(bufferlist[i]);
2330 +                               if (!buffer_uptodate(bufferlist[i]))
2331 +                                       write_error = 1;
2332 +                               brelse(bufferlist[i]);
2333 +                       }
2334 +                       buffercount = 0;
2335 +               }
2336 +               if (write_error)
2337 +                       break;
2338 +               block++;
2339 +               offset = 0;
2340 +               c = sb->s_blocksize;
2341 +       } while (count);
2342 +
2343 +       if (buffercount)
2344 +       {
2345 +               ll_rw_block(WRITE, buffercount, bufferlist);
2346 +               for (i=0; i<buffercount; i++)
2347 +               {
2348 +                       wait_on_buffer(bufferlist[i]);
2349 +                       if (!buffer_uptodate(bufferlist[i]))
2350 +                               write_error = 1;
2351 +                       brelse(bufferlist[i]);
2352 +               }
2353 +       }
2354 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
2355 +               pos -= udf_file_entry_alloc_offset(inode);
2356 +
2357 +       if (pos > inode->i_size)
2358 +               inode->i_size = pos;
2359 +       if (filp->f_flags & O_SYNC)
2360 +               ; /* Do something */
2361 +       inode->i_ctime = inode->i_mtime = CURRENT_TIME;
2362 +       UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME;
2363 +       *ppos = pos;
2364 +       mark_inode_dirty(inode);
2365 +       return written;
2366 +}
2367 +
2368 +/*
2369 + * udf_ioctl
2370 + *
2371 + * PURPOSE
2372 + *     Issue an ioctl.
2373 + *
2374 + * DESCRIPTION
2375 + *     Optional - sys_ioctl() will return -ENOTTY if this routine is not
2376 + *     available, and the ioctl cannot be handled without filesystem help.
2377 + *
2378 + *     sys_ioctl() handles these ioctls that apply only to regular files:
2379 + *             FIBMAP [requires udf_bmap()], FIGETBSZ, FIONREAD
2380 + *     These ioctls are also handled by sys_ioctl():
2381 + *             FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC
2382 + *     All other ioctls are passed to the filesystem.
2383 + *
2384 + *     Refer to sys_ioctl() in fs/ioctl.c
2385 + *     sys_ioctl() -> .
2386 + *
2387 + * PRE-CONDITIONS
2388 + *     inode                   Pointer to inode that ioctl was issued on.
2389 + *     filp                    Pointer to file that ioctl was issued on.
2390 + *     cmd                     The ioctl command.
2391 + *     arg                     The ioctl argument [can be interpreted as a
2392 + *                             user-space pointer if desired].
2393 + *
2394 + * POST-CONDITIONS
2395 + *     <return>                Success (>=0) or an error code (<=0) that
2396 + *                             sys_ioctl() will return.
2397 + *
2398 + * HISTORY
2399 + *     July 1, 1997 - Andrew E. Mileski
2400 + *     Written, tested, and released.
2401 + */
2402 +int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2403 +       unsigned long arg)
2404 +{
2405 +       int result = -1;
2406 +       struct buffer_head *bh = NULL;
2407 +       Uint16 ident;
2408 +       long_ad eaicb;
2409 +       Uint8 *ea = NULL;
2410 +
2411 +       if ( permission(inode, MAY_READ) != 0 )
2412 +       {
2413 +               udf_debug("no permission to access inode %lu\n",
2414 +                                               inode->i_ino);
2415 +               return -EPERM;
2416 +       }
2417 +
2418 +       if ( !arg )
2419 +       {
2420 +               udf_debug("invalid argument to udf_ioctl\n");
2421 +               return -EINVAL;
2422 +       }
2423 +
2424 +       /* first, do ioctls that don't need to udf_read */
2425 +       switch (cmd)
2426 +       {
2427 +               case UDF_GETVOLIDENT:
2428 +                       if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
2429 +                               result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
2430 +                       return result;
2431 +
2432 +       }
2433 +
2434 +       /* ok, we need to read the inode */
2435 +       bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
2436 +
2437 +       if (!bh || (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY))
2438 +       {
2439 +               udf_debug("bread failed (ino=%ld) or ident (%d) != TID_(EXTENDED_)FILE_ENTRY",
2440 +                       inode->i_ino, ident);
2441 +               return -EFAULT;
2442 +       }
2443 +
2444 +       if (UDF_I_EXTENDED_FE(inode) == 0)
2445 +       {
2446 +               struct FileEntry *fe;
2447 +
2448 +               fe = (struct FileEntry *)bh->b_data;
2449 +               eaicb = lela_to_cpu(fe->extendedAttrICB);
2450 +               if (UDF_I_LENEATTR(inode))
2451 +                       ea = fe->extendedAttr;
2452 +       }
2453 +       else
2454 +       {
2455 +               struct ExtendedFileEntry *efe;
2456 +
2457 +               efe = (struct ExtendedFileEntry *)bh->b_data;
2458 +               eaicb = lela_to_cpu(efe->extendedAttrICB);
2459 +               if (UDF_I_LENEATTR(inode))
2460 +                       ea = efe->extendedAttr;
2461 +       }
2462 +
2463 +       switch (cmd) 
2464 +       {
2465 +               case UDF_GETEASIZE:
2466 +                       if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0) 
2467 +                               result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
2468 +                       break;
2469 +
2470 +               case UDF_GETEABLOCK:
2471 +                       if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0) 
2472 +                               result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));
2473 +                       break;
2474 +
2475 +               default:
2476 +                       udf_debug("ino=%ld, cmd=%d\n", inode->i_ino, cmd);
2477 +                       break;
2478 +       }
2479 +
2480 +       udf_release_data(bh);
2481 +       return result;
2482 +}
2483 +
2484 +/*
2485 + * udf_release_file
2486 + *
2487 + * PURPOSE
2488 + *  Called when all references to the file are closed
2489 + *
2490 + * DESCRIPTION
2491 + *  Discard prealloced blocks
2492 + *
2493 + * HISTORY
2494 + *
2495 + */
2496 +static int udf_release_file(struct inode * inode, struct file * filp)
2497 +{
2498 +       if (filp->f_mode & FMODE_WRITE)
2499 +               udf_discard_prealloc(inode);
2500 +       return 0;
2501 +}
2502 +
2503 +#if BITS_PER_LONG < 64
2504 +/*
2505 + * udf_open_file
2506 + *
2507 + * PURPOSE
2508 + *  Called when an inode is about to be open.
2509 + *
2510 + * DESCRIPTION
2511 + *  Use this to disallow opening RW large files on 32 bit systems.
2512 + *
2513 + * HISTORY
2514 + *
2515 + */
2516 +static int udf_open_file(struct inode * inode, struct file * filp)
2517 +{
2518 +       if (inode->i_size == (Uint32)-1 && (filp->f_mode & FMODE_WRITE))
2519 +               return -EFBIG;
2520 +       return 0;
2521 +}
2522 +#endif
2523 +
2524 +static struct file_operations udf_file_operations = {
2525 +       udf_file_llseek,                /* llseek */
2526 +       generic_file_read,              /* read */
2527 +       udf_file_write,                 /* write */
2528 +       NULL,                                   /* readdir */
2529 +       NULL,                                   /* poll */
2530 +       udf_ioctl,                              /* ioctl */
2531 +       generic_file_mmap,              /* mmap */
2532 +#if BITS_PER_LONG == 64
2533 +       NULL,                                   /* open */
2534 +#else
2535 +       udf_open_file,                  /* open */
2536 +#endif
2537 +       NULL,                                   /* flush */
2538 +       udf_release_file,               /* release */
2539 +       udf_sync_file,                  /* fsync */
2540 +       NULL,                                   /* fasync */
2541 +       NULL,                                   /* check_media_change */
2542 +       NULL,                                   /* revalidate */
2543 +       NULL                                    /* lock */
2544 +};
2545 +
2546 +struct inode_operations udf_file_inode_operations = {
2547 +       &udf_file_operations,
2548 +       NULL,                                   /* create */
2549 +       NULL,                                   /* lookup */
2550 +       NULL,                                   /* link */
2551 +       NULL,                                   /* unlink */
2552 +       NULL,                                   /* symlink */
2553 +       NULL,                                   /* mkdir */
2554 +       NULL,                                   /* rmdir */
2555 +       NULL,                                   /* mknod */
2556 +       NULL,                                   /* rename */
2557 +       NULL,                                   /* readlink */
2558 +       NULL,                                   /* follow_link */
2559 +       generic_readpage,               /* readpage */
2560 +       NULL,                                   /* writepage */
2561 +       udf_bmap,                               /* bmap */
2562 +       udf_truncate,                   /* truncate */
2563 +       NULL,                                   /* permission */
2564 +       NULL,                                   /* smap */
2565 +       NULL,                                   /* updatepage */
2566 +       NULL                                    /* revalidate */
2567 +};
2568 +
2569 +struct inode_operations udf_file_inode_operations_adinicb = {
2570 +       &udf_file_operations,
2571 +       NULL,                                   /* create */
2572 +       NULL,                                   /* lookup */
2573 +       NULL,                                   /* link */
2574 +       NULL,                                   /* unlink */
2575 +       NULL,                                   /* symlink */
2576 +       NULL,                                   /* mkdir */
2577 +       NULL,                                   /* rmdir */
2578 +       NULL,                                   /* mknod */
2579 +       NULL,                                   /* rename */
2580 +       NULL,                                   /* readlink */
2581 +       NULL,                                   /* follow_link */
2582 +       udf_readpage_adinicb,   /* readpage */
2583 +       NULL,                                   /* writepage */
2584 +       NULL,                                   /* bmap */
2585 +       udf_truncate_adinicb,   /* truncate */
2586 +       NULL,                                   /* permission */
2587 +       NULL,                                   /* smap */
2588 +       NULL,                                   /* updatepage */
2589 +       NULL                                    /* revalidate */
2590 +};
2591 diff -Nru linux/fs/udf/fsync.c linux.new/fs/udf/fsync.c
2592 --- linux/fs/udf/fsync.c        Thu Jan  1 01:00:00 1970
2593 +++ linux.new/fs/udf/fsync.c    Fri Sep  7 11:32:16 2001
2594 @@ -0,0 +1,115 @@
2595 +/*
2596 + * fsync.c
2597 + *
2598 + * PURPOSE
2599 + *  Fsync handling routines for the OSTA-UDF(tm) filesystem.
2600 + *
2601 + * CONTACTS
2602 + *  E-mail regarding any portion of the Linux UDF file system should be
2603 + *  directed to the development team mailing list (run by majordomo):
2604 + *      linux_udf@hootie.lvld.hp.com
2605 + *
2606 + * COPYRIGHT
2607 + *  This file is distributed under the terms of the GNU General Public
2608 + *  License (GPL). Copies of the GPL can be obtained from:
2609 + *      ftp://prep.ai.mit.edu/pub/gnu/GPL
2610 + *  Each contributing author retains all rights to their own work.
2611 + *
2612 + *  (C) 1999-2000 Ben Fennema
2613 + *  (C) 1999-2000 Stelias Computing Inc
2614 + *
2615 + * HISTORY
2616 + *
2617 + *  05/22/99 blf  Created.
2618 + */
2619 +
2620 +#include "udfdecl.h"
2621 +
2622 +#include <linux/fs.h>
2623 +#include <linux/udf_fs.h>
2624 +#include "udf_i.h"
2625 +
2626 +static int sync_block (struct inode * inode, Uint32 * block, int wait)
2627 +{
2628 +       struct buffer_head * bh;
2629 +       
2630 +       if (!*block)
2631 +               return 0;
2632 +       bh = get_hash_table (inode->i_dev, *block, inode->i_sb->s_blocksize);
2633 +       if (!bh)
2634 +               return 0;
2635 +       if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
2636 +               brelse (bh);
2637 +               return -1;
2638 +       }
2639 +       if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
2640 +               brelse (bh);
2641 +               return 0;
2642 +       }
2643 +       ll_rw_block (WRITE, 1, &bh);
2644 +       bh->b_count--;
2645 +       return 0;
2646 +}
2647 +
2648 +static int sync_extent (struct inode * inode, lb_addr *loc, Uint32 *len, int wait)
2649 +{
2650 +       Uint32 i, block;
2651 +       int rc, err = 0;
2652 +
2653 +       for (i = 0; i < *len; i++)
2654 +       {
2655 +               block = udf_get_lb_pblock(inode->i_sb, *loc, i);
2656 +               rc = sync_block (inode, &block, wait);
2657 +               if (rc)
2658 +                       err = rc;
2659 +       }
2660 +       return err;
2661 +}
2662 +
2663 +static int sync_all_extents(struct inode * inode, int wait)
2664 +{
2665 +       lb_addr bloc, eloc;
2666 +       Uint32 extoffset, elen, offset;
2667 +       int err = 0, etype;
2668 +       struct buffer_head *bh = NULL;
2669 +       
2670 +       if ((etype = inode_bmap(inode, 0, &bloc, &extoffset, &eloc, &elen, &offset, &bh)) != -1)
2671 +       {
2672 +               err |= sync_extent(inode, &eloc, &elen, wait);
2673 +
2674 +               while ((etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
2675 +               {
2676 +                       if (etype == EXTENT_RECORDED_ALLOCATED)
2677 +                               err |= sync_extent(inode, &eloc, &elen, wait);
2678 +               }
2679 +       }
2680 +       udf_release_data(bh);
2681 +       return err;
2682 +}
2683 +
2684 +/*
2685 + *     File may be NULL when we are called. Perhaps we shouldn't
2686 + *     even pass file to fsync ?
2687 + */
2688 +
2689 +int udf_sync_file(struct file * file, struct dentry *dentry)
2690 +{
2691 +       int wait, err = 0;
2692 +       struct inode *inode = dentry->d_inode;
2693 +
2694 +       if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
2695 +       {
2696 +               /*
2697 +                * Don't sync fast links! or ICB_FLAG_AD_IN_ICB
2698 +                */
2699 +               goto skip;
2700 +       }
2701 +
2702 +       for (wait=0; wait<=1; wait++)
2703 +       {
2704 +               err |= sync_all_extents (inode, wait);
2705 +       }
2706 +skip:
2707 +       err |= udf_sync_inode (inode);
2708 +       return err ? -EIO : 0;
2709 +}
2710 diff -Nru linux/fs/udf/ialloc.c linux.new/fs/udf/ialloc.c
2711 --- linux/fs/udf/ialloc.c       Thu Jan  1 01:00:00 1970
2712 +++ linux.new/fs/udf/ialloc.c   Fri Sep  7 11:32:16 2001
2713 @@ -0,0 +1,195 @@
2714 +/*
2715 + * ialloc.c
2716 + *
2717 + * PURPOSE
2718 + *     Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
2719 + *
2720 + * CONTACTS
2721 + *     E-mail regarding any portion of the Linux UDF file system should be
2722 + *     directed to the development team mailing list (run by majordomo):
2723 + *             linux_udf@hootie.lvld.hp.com
2724 + *
2725 + * COPYRIGHT
2726 + *     This file is distributed under the terms of the GNU General Public
2727 + *     License (GPL). Copies of the GPL can be obtained from:
2728 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
2729 + *     Each contributing author retains all rights to their own work.
2730 + *
2731 + *  (C) 1998-2000 Ben Fennema
2732 + *
2733 + * HISTORY
2734 + *
2735 + *  02/24/99 blf  Created.
2736 + *
2737 + */
2738 +
2739 +#include "udfdecl.h"
2740 +#include <linux/fs.h>
2741 +#include <linux/locks.h>
2742 +#include <linux/quotaops.h>
2743 +#include <linux/udf_fs.h>
2744 +#include <linux/ext2_fs.h>
2745 +
2746 +#include "udf_i.h"
2747 +#include "udf_sb.h"
2748 +
2749 +void udf_free_inode(struct inode * inode)
2750 +{
2751 +       struct super_block * sb = inode->i_sb;
2752 +       int is_directory;
2753 +       unsigned long ino;
2754 +
2755 +       if (!inode->i_dev)
2756 +       {
2757 +               udf_debug("inode has no device\n");
2758 +               return;
2759 +       }
2760 +       if (inode->i_count > 1)
2761 +       {
2762 +               udf_debug("inode has count=%d\n", inode->i_count);
2763 +               return;
2764 +       }
2765 +       if (inode->i_nlink)
2766 +       {
2767 +               udf_debug("inode has nlink=%d\n", inode->i_nlink);
2768 +               return;
2769 +       }
2770 +       if (!sb)
2771 +       {
2772 +               udf_debug("inode on nonexistent device\n");
2773 +               return;
2774 +       }
2775 +
2776 +       ino = inode->i_ino;
2777 +
2778 +       /*
2779 +        * Note: we must free any quota before locking the superblock,
2780 +        * as writing the quota to disk may need the lock as well.
2781 +        */
2782 +       DQUOT_FREE_INODE(sb, inode);
2783 +       DQUOT_DROP(inode);
2784 +
2785 +       lock_super(sb);
2786 +
2787 +       is_directory = S_ISDIR(inode->i_mode);
2788 +
2789 +       clear_inode(inode);
2790 +
2791 +       if (UDF_SB_LVIDBH(sb))
2792 +       {
2793 +               if (is_directory)
2794 +                       UDF_SB_LVIDIU(sb)->numDirs =
2795 +                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
2796 +               else
2797 +                       UDF_SB_LVIDIU(sb)->numFiles =
2798 +                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
2799 +               
2800 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
2801 +       }
2802 +
2803 +       unlock_super(sb);
2804 +
2805 +       udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
2806 +}
2807 +
2808 +struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
2809 +{
2810 +       struct super_block *sb;
2811 +       struct inode * inode;
2812 +       int block;
2813 +       Uint32 start = UDF_I_LOCATION(dir).logicalBlockNum;
2814 +
2815 +       inode = get_empty_inode();
2816 +       if (!inode)
2817 +       {
2818 +               *err = -ENOMEM;
2819 +               return NULL;
2820 +       }
2821 +       sb = dir->i_sb;
2822 +       inode->i_sb = sb;
2823 +       inode->i_flags = 0;
2824 +       *err = -ENOSPC;
2825 +
2826 +       block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
2827 +               start, err);
2828 +       if (*err)
2829 +       {
2830 +               iput(inode);
2831 +               return NULL;
2832 +       }
2833 +       lock_super(sb);
2834 +
2835 +       if (UDF_SB_LVIDBH(sb))
2836 +       {
2837 +               struct LogicalVolHeaderDesc *lvhd;
2838 +               Uint64 uniqueID;
2839 +               lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
2840 +               if (S_ISDIR(mode))
2841 +                       UDF_SB_LVIDIU(sb)->numDirs =
2842 +                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
2843 +               else
2844 +                       UDF_SB_LVIDIU(sb)->numFiles =
2845 +                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
2846 +               UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
2847 +               if (!(++uniqueID & 0x00000000FFFFFFFFUL))
2848 +                       uniqueID += 16;
2849 +               lvhd->uniqueID = cpu_to_le64(uniqueID);
2850 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
2851 +       }
2852 +       inode->i_mode = mode;
2853 +       inode->i_sb = sb;
2854 +       inode->i_nlink = 1;
2855 +       inode->i_dev = sb->s_dev;
2856 +       inode->i_uid = current->fsuid;
2857 +       if (test_opt (sb, GRPID))
2858 +               inode->i_gid = dir->i_gid;
2859 +       else if (dir->i_mode & S_ISGID)
2860 +       {
2861 +               inode->i_gid = dir->i_gid;
2862 +               if (S_ISDIR(mode))
2863 +                       mode |= S_ISGID;
2864 +       }
2865 +       else
2866 +               inode->i_gid = current->fsgid;
2867 +
2868 +       UDF_I_LOCATION(inode).logicalBlockNum = block;
2869 +       UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
2870 +       inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
2871 +       inode->i_blksize = PAGE_SIZE;
2872 +       inode->i_blocks = 0;
2873 +       inode->i_size = 0;
2874 +       UDF_I_LENEATTR(inode) = 0;
2875 +       UDF_I_LENALLOC(inode) = 0;
2876 +       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
2877 +       {
2878 +               UDF_I_EXTENDED_FE(inode) = 1;
2879 +               UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
2880 +       }
2881 +       else
2882 +               UDF_I_EXTENDED_FE(inode) = 0;
2883 +       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
2884 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB;
2885 +       else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
2886 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
2887 +       else
2888 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
2889 +       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2890 +       UDF_I_UMTIME(inode) = UDF_I_UATIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;
2891 +       UDF_I_NEW_INODE(inode) = 1;
2892 +       inode->i_op = NULL;
2893 +       insert_inode_hash(inode);
2894 +       mark_inode_dirty(inode);
2895 +
2896 +       unlock_super(sb);
2897 +       if (DQUOT_ALLOC_INODE(sb, inode))
2898 +       {
2899 +               sb->dq_op->drop(inode);
2900 +               inode->i_nlink = 0;
2901 +               iput(inode);
2902 +               *err = -EDQUOT;
2903 +               return NULL;
2904 +       }
2905 +
2906 +       *err = 0;
2907 +       return inode;
2908 +}
2909 diff -Nru linux/fs/udf/inode.c linux.new/fs/udf/inode.c
2910 --- linux/fs/udf/inode.c        Thu Jan  1 01:00:00 1970
2911 +++ linux.new/fs/udf/inode.c    Fri Sep  7 11:32:16 2001
2912 @@ -0,0 +1,2022 @@
2913 +/*
2914 + * inode.c
2915 + *
2916 + * PURPOSE
2917 + *  Inode handling routines for the OSTA-UDF(tm) filesystem.
2918 + *
2919 + * CONTACTS
2920 + *  E-mail regarding any portion of the Linux UDF file system should be
2921 + *  directed to the development team mailing list (run by majordomo):
2922 + *    linux_udf@hootie.lvld.hp.com
2923 + *
2924 + * COPYRIGHT
2925 + *  This file is distributed under the terms of the GNU General Public
2926 + *  License (GPL). Copies of the GPL can be obtained from:
2927 + *    ftp://prep.ai.mit.edu/pub/gnu/GPL
2928 + *  Each contributing author retains all rights to their own work.
2929 + *
2930 + *  (C) 1998 Dave Boynton
2931 + *  (C) 1998-2000 Ben Fennema
2932 + *  (C) 1999-2000 Stelias Computing Inc
2933 + *
2934 + * HISTORY
2935 + *
2936 + *  10/04/98 dgb  Added rudimentary directory functions
2937 + *  10/07/98      Fully working udf_bmap! It works!
2938 + *  11/25/98      bmap altered to better support extents
2939 + *  12/06/98 blf  partition support in udf_iget, udf_bmap and udf_read_inode
2940 + *  12/12/98      rewrote udf_bmap to handle next extents and descs across
2941 + *                block boundaries (which is not actually allowed)
2942 + *  12/20/98      added support for strategy 4096
2943 + *  03/07/99      rewrote udf_bmap (again)
2944 + *                New funcs, inode_bmap, udf_next_aext
2945 + *  04/19/99      Support for writing device EA's for major/minor #
2946 + */
2947 +
2948 +#include "udfdecl.h"
2949 +#include <linux/locks.h>
2950 +#include <linux/mm.h>
2951 +
2952 +#include "udf_i.h"
2953 +#include "udf_sb.h"
2954 +
2955 +#define EXTENT_MERGE_SIZE 5
2956 +
2957 +static mode_t udf_convert_permissions(struct FileEntry *);
2958 +static int udf_update_inode(struct inode *, int);
2959 +static void udf_fill_inode(struct inode *, struct buffer_head *);
2960 +static struct buffer_head *inode_getblk(struct inode *, long, int, int *);
2961 +static void udf_split_extents(struct inode *, int *, int, int,
2962 +       long_ad [EXTENT_MERGE_SIZE], int *);
2963 +static void udf_prealloc_extents(struct inode *, int, int,
2964 +        long_ad [EXTENT_MERGE_SIZE], int *);
2965 +static void udf_merge_extents(struct inode *,
2966 +        long_ad [EXTENT_MERGE_SIZE], int *);
2967 +static void udf_update_extents(struct inode *,
2968 +       long_ad [EXTENT_MERGE_SIZE], int, int,
2969 +       lb_addr, Uint32, struct buffer_head **);
2970 +
2971 +/*
2972 + * udf_put_inode
2973 + *
2974 + * PURPOSE
2975 + *
2976 + * DESCRIPTION
2977 + *     This routine is called whenever the kernel no longer needs the inode.
2978 + *
2979 + * HISTORY
2980 + *     July 1, 1997 - Andrew E. Mileski
2981 + *     Written, tested, and released.
2982 + *
2983 + *  Called at each iput()
2984 + */
2985 +void udf_put_inode(struct inode * inode)
2986 +{
2987 +       if (!(inode->i_sb->s_flags & MS_RDONLY))
2988 +       {
2989 +               udf_discard_prealloc(inode);
2990 +               /* write the root inode on put, if dirty */
2991 +               if (!inode->i_sb->s_root && inode->i_state & I_DIRTY)
2992 +                       udf_update_inode(inode, IS_SYNC(inode));
2993 +       }
2994 +}
2995 +
2996 +/*
2997 + * udf_delete_inode
2998 + *
2999 + * PURPOSE
3000 + *     Clean-up before the specified inode is destroyed.
3001 + *
3002 + * DESCRIPTION
3003 + *     This routine is called when the kernel destroys an inode structure
3004 + *     ie. when iput() finds i_count == 0.
3005 + *
3006 + * HISTORY
3007 + *     July 1, 1997 - Andrew E. Mileski
3008 + *     Written, tested, and released.
3009 + *
3010 + *  Called at the last iput() if i_nlink is zero.
3011 + */
3012 +void udf_delete_inode(struct inode * inode)
3013 +{
3014 +       if (is_bad_inode(inode))
3015 +               return;
3016 +       inode->i_size = 0;
3017 +       if (inode->i_blocks)
3018 +       {
3019 +               if (inode->i_op && inode->i_op->truncate)
3020 +                       inode->i_op->truncate(inode);
3021 +               else
3022 +                       udf_truncate(inode);
3023 +       }
3024 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
3025 +               udf_truncate_adinicb(inode);
3026 +       udf_update_inode(inode, IS_SYNC(inode));
3027 +       udf_free_inode(inode);
3028 +}
3029 +
3030 +void udf_discard_prealloc(struct inode * inode)
3031 +{
3032 +       if (inode->i_size && UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
3033 +               udf_trunc(inode);
3034 +}
3035 +
3036 +void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
3037 +{
3038 +       int block, newblock;
3039 +       struct buffer_head *sbh = NULL, *dbh = NULL;
3040 +       lb_addr bloc, eloc;
3041 +       Uint32 elen, extoffset;
3042 +
3043 +       if (!UDF_I_LENALLOC(inode))
3044 +       {
3045 +               if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
3046 +                       UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
3047 +               else
3048 +                       UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
3049 +               mark_inode_dirty(inode);
3050 +               inode->i_op = &udf_file_inode_operations;
3051 +               return;
3052 +       }
3053 +
3054 +       /* alloc block, and copy data to it */
3055 +       block = udf_new_block(inode,
3056 +               UDF_I_LOCATION(inode).partitionReferenceNum,
3057 +               UDF_I_LOCATION(inode).logicalBlockNum, err);
3058 +
3059 +       if (!(block))
3060 +               return;
3061 +       newblock = udf_get_pblock(inode->i_sb, block,
3062 +               UDF_I_LOCATION(inode).partitionReferenceNum, 0);
3063 +       if (!newblock)
3064 +               return;
3065 +       sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
3066 +       if (!sbh)
3067 +               return;
3068 +       dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize);
3069 +       if (!dbh)
3070 +               return;
3071 +
3072 +       memcpy(dbh->b_data, sbh->b_data + udf_file_entry_alloc_offset(inode),
3073 +               UDF_I_LENALLOC(inode));
3074 +               
3075 +       mark_buffer_dirty(dbh, 1);
3076 +       udf_release_data(dbh);
3077 +
3078 +       memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
3079 +               0, UDF_I_LENALLOC(inode));
3080 +
3081 +       UDF_I_LENALLOC(inode) = 0;
3082 +       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
3083 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
3084 +       else
3085 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
3086 +       bloc = UDF_I_LOCATION(inode);
3087 +       eloc.logicalBlockNum = block;
3088 +       eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
3089 +       elen = newsize > inode->i_sb->s_blocksize ?
3090 +               inode->i_sb->s_blocksize : newsize;
3091 +       extoffset = udf_file_entry_alloc_offset(inode);
3092 +       udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
3093 +       /* UniqueID stuff */
3094 +
3095 +       inode->i_blocks = inode->i_sb->s_blocksize / 512;
3096 +       mark_buffer_dirty(sbh, 1);
3097 +       udf_release_data(sbh);
3098 +       mark_inode_dirty(inode);
3099 +       inode->i_version ++;
3100 +       inode->i_op = &udf_file_inode_operations;
3101 +}
3102 +
3103 +struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
3104 +{
3105 +       int newblock;
3106 +       struct buffer_head *sbh = NULL, *dbh = NULL;
3107 +       lb_addr bloc, eloc;
3108 +       Uint32 elen, extoffset;
3109 +
3110 +       struct udf_fileident_bh sfibh, dfibh;
3111 +       int f_pos = udf_ext0_offset(inode) >> 2;
3112 +       int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
3113 +       struct FileIdentDesc cfi, *sfi, *dfi;
3114 +
3115 +       if (!inode->i_size)
3116 +       {
3117 +               if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
3118 +                       UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
3119 +               else
3120 +                       UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
3121 +               mark_inode_dirty(inode);
3122 +               return NULL;
3123 +       }
3124 +
3125 +       /* alloc block, and copy data to it */
3126 +       *block = udf_new_block(inode,
3127 +               UDF_I_LOCATION(inode).partitionReferenceNum,
3128 +               UDF_I_LOCATION(inode).logicalBlockNum, err);
3129 +
3130 +       if (!(*block))
3131 +               return NULL;
3132 +       newblock = udf_get_pblock(inode->i_sb, *block,
3133 +               UDF_I_LOCATION(inode).partitionReferenceNum, 0);
3134 +       if (!newblock)
3135 +               return NULL;
3136 +       sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
3137 +       if (!sbh)
3138 +               return NULL;
3139 +       dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize);
3140 +       if (!dbh)
3141 +               return NULL;
3142 +
3143 +       sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
3144 +       sfibh.sbh = sfibh.ebh = sbh;
3145 +       dfibh.soffset = dfibh.eoffset = 0;
3146 +       dfibh.sbh = dfibh.ebh = dbh;
3147 +       while ( (f_pos < size) )
3148 +       {
3149 +               sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
3150 +               if (!sfi)
3151 +               {
3152 +                       udf_release_data(sbh);
3153 +                       udf_release_data(dbh);
3154 +                       return NULL;
3155 +               }
3156 +               sfi->descTag.tagLocation = *block;
3157 +               dfibh.soffset = dfibh.eoffset;
3158 +               dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
3159 +               dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset);
3160 +               if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse,
3161 +                       sfi->fileIdent + sfi->lengthOfImpUse))
3162 +               {
3163 +                       udf_release_data(sbh);
3164 +                       udf_release_data(dbh);
3165 +                       return NULL;
3166 +               }
3167 +       }
3168 +       mark_buffer_dirty(dbh, 1);
3169 +
3170 +       memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
3171 +               0, UDF_I_LENALLOC(inode));
3172 +
3173 +       UDF_I_LENALLOC(inode) = 0;
3174 +       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
3175 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
3176 +       else
3177 +               UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
3178 +       bloc = UDF_I_LOCATION(inode);
3179 +       eloc.logicalBlockNum = *block;
3180 +       eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
3181 +       elen = inode->i_size;
3182 +       extoffset = udf_file_entry_alloc_offset(inode);
3183 +       udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
3184 +       /* UniqueID stuff */
3185 +
3186 +       inode->i_blocks = inode->i_sb->s_blocksize / 512;
3187 +       mark_buffer_dirty(sbh, 1);
3188 +       udf_release_data(sbh);
3189 +       mark_inode_dirty(inode);
3190 +       inode->i_version ++;
3191 +       return dbh;
3192 +}
3193 +
3194 +struct buffer_head * udf_getblk(struct inode * inode, long block,
3195 +       int create, int * err)
3196 +{
3197 +       *err = -EIO;
3198 +       if (block < 0)
3199 +       {
3200 +               udf_warning(inode->i_sb, "udf_getblk", "block < 0");
3201 +               return NULL;
3202 +       }
3203 +
3204 +       if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
3205 +       {
3206 +               UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
3207 +               UDF_I_NEXT_ALLOC_GOAL(inode) ++;
3208 +       }
3209 +
3210 +       *err = -ENOSPC;
3211 +       return inode_getblk(inode, block, create, err);
3212 +}
3213 +
3214 +static struct buffer_head * inode_getblk(struct inode * inode, long block,
3215 +       int create, int * err)
3216 +{
3217 +       struct buffer_head *pbh = NULL, *cbh = NULL, *result = NULL;
3218 +       long_ad laarr[EXTENT_MERGE_SIZE];
3219 +       Uint32 pextoffset = 0, cextoffset = 0, nextoffset = 0;
3220 +       int count = 0, startnum = 0, endnum = 0;
3221 +       Uint32 elen = 0;
3222 +       lb_addr eloc, pbloc = UDF_I_LOCATION(inode), cbloc = UDF_I_LOCATION(inode);
3223 +       int c = 1;
3224 +       int lbcount = 0, b_off = 0, offset = 0;
3225 +       Uint32 newblocknum, newblock;
3226 +       char etype;
3227 +       int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
3228 +       char lastblock = 0;
3229 +
3230 +       pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
3231 +       b_off = block << inode->i_sb->s_blocksize_bits;
3232 +       pbloc = cbloc = UDF_I_LOCATION(inode);
3233 +
3234 +       /* find the extent which contains the block we are looking for.
3235 +       alternate between laarr[0] and laarr[1] for locations of the
3236 +       current extent, and the previous extent */
3237 +       do
3238 +       {
3239 +               if (pbh != cbh)
3240 +               {
3241 +                       udf_release_data(pbh);
3242 +                       pbh = cbh;
3243 +                       cbh->b_count ++;
3244 +                       pbloc = cbloc;
3245 +               }
3246 +
3247 +               lbcount += elen;
3248 +
3249 +               pextoffset = cextoffset;
3250 +               cextoffset = nextoffset;
3251 +
3252 +               if ((etype = udf_next_aext(inode, &cbloc, &nextoffset, &eloc, &elen, &cbh, 1)) == -1)
3253 +                       break;
3254 +
3255 +               c = !c;
3256 +
3257 +               laarr[c].extLength = (etype << 30) | elen;
3258 +               laarr[c].extLocation = eloc;
3259 +
3260 +               if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
3261 +                       pgoal = eloc.logicalBlockNum +
3262 +                               ((elen + inode->i_sb->s_blocksize - 1) >>
3263 +                               inode->i_sb->s_blocksize);
3264 +
3265 +               count ++;
3266 +       } while (lbcount + elen <= b_off);
3267 +
3268 +       b_off -= lbcount;
3269 +       offset = b_off >> inode->i_sb->s_blocksize_bits;
3270 +
3271 +       /* if the extent is allocated and recorded, return the block
3272 +       if the extent is not a multiple of the blocksize, round up */
3273 +
3274 +       if (etype == EXTENT_RECORDED_ALLOCATED)
3275 +       {
3276 +               if (elen & (inode->i_sb->s_blocksize - 1))
3277 +               {
3278 +                       elen = (EXTENT_RECORDED_ALLOCATED << 30) |
3279 +                               ((elen + inode->i_sb->s_blocksize - 1) &
3280 +                               ~(inode->i_sb->s_blocksize - 1));
3281 +                       etype = udf_write_aext(inode, cbloc, &cextoffset, eloc, elen, cbh, 1);
3282 +               }
3283 +               udf_release_data(pbh);
3284 +               udf_release_data(cbh);
3285 +               newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
3286 +               return getblk(inode->i_dev, newblock, inode->i_sb->s_blocksize);
3287 +       }
3288 +
3289 +       if (etype == -1)
3290 +       {
3291 +               endnum = startnum = ((count > 1) ? 1 : count);
3292 +               if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
3293 +               {
3294 +                       laarr[c].extLength =
3295 +                               (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
3296 +                               (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
3297 +                                       inode->i_sb->s_blocksize - 1) &
3298 +                               ~(inode->i_sb->s_blocksize - 1));
3299 +               }
3300 +               c = !c;
3301 +               laarr[c].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
3302 +                       ((offset + 1) << inode->i_sb->s_blocksize_bits);
3303 +               memset(&laarr[c].extLocation, 0x00, sizeof(lb_addr));
3304 +               count ++;
3305 +               endnum ++;
3306 +               lastblock = 1;
3307 +       }
3308 +       else
3309 +               endnum = startnum = ((count > 2) ? 2 : count);
3310 +
3311 +       /* if the current extent is in position 0, swap it with the previous */
3312 +       if (!c && count != 1)
3313 +       {
3314 +               laarr[2] = laarr[0];
3315 +               laarr[0] = laarr[1];
3316 +               laarr[1] = laarr[2];
3317 +               c = 1;
3318 +       }
3319 +
3320 +       /* if the current block is located in a extent, read the next extent */
3321 +       if (etype != -1)
3322 +       {
3323 +               if ((etype = udf_next_aext(inode, &cbloc, &nextoffset, &eloc, &elen, &cbh, 0)) != -1)
3324 +               {
3325 +                       laarr[c+1].extLength = (etype << 30) | elen;
3326 +                       laarr[c+1].extLocation = eloc;
3327 +                       count ++;
3328 +                       startnum ++;
3329 +                       endnum ++;
3330 +               }
3331 +               else
3332 +                       lastblock = 1;
3333 +       }
3334 +       udf_release_data(cbh);
3335 +
3336 +       *err = -EFBIG;
3337 +       if (!create && etype != EXTENT_NOT_RECORDED_ALLOCATED)
3338 +               goto dont_create;
3339 +
3340 +       {
3341 +               unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
3342 +               if (limit < RLIM_INFINITY)
3343 +               {
3344 +                       limit >>= inode->i_sb->s_blocksize_bits;
3345 +                       if (block >= limit)
3346 +                       {
3347 +                               send_sig(SIGXFSZ, current, 0);
3348 +dont_create:
3349 +                               *err = -EFBIG;
3350 +                               return NULL;
3351 +                       }
3352 +               }
3353 +       }
3354 +
3355 +       /* if the current extent is not recorded but allocated, get the
3356 +               block in the extent corresponding to the requested block */
3357 +       if ((laarr[c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
3358 +               newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
3359 +       else /* otherwise, allocate a new block */
3360 +       {
3361 +               if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
3362 +                       goal = UDF_I_NEXT_ALLOC_GOAL(inode);
3363 +
3364 +               if (!goal)
3365 +               {
3366 +                       if (!(goal = pgoal))
3367 +                               goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
3368 +               }
3369 +
3370 +               if (!(newblocknum = udf_new_block(inode,
3371 +                       UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
3372 +               {
3373 +                       udf_release_data(pbh);
3374 +                       *err = -ENOSPC;
3375 +                       return NULL;
3376 +               }
3377 +       }
3378 +
3379 +       /* if the extent the requsted block is located in contains multiple blocks,
3380 +       split the extent into at most three extents. blocks prior to requested
3381 +       block, requested block, and blocks after requested block */
3382 +       udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
3383 +
3384 +#ifdef UDF_PREALLOCATE
3385 +       /* preallocate blocks */
3386 +       udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
3387 +#endif
3388 +
3389 +       /* merge any continuous blocks in laarr */
3390 +       udf_merge_extents(inode, laarr, &endnum);
3391 +
3392 +       /* write back the new extents, inserting new extents if the new number
3393 +       of extents is greater than the old number, and deleting extents if
3394 +       the new number of extents is less than the old number */
3395 +       udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);
3396 +
3397 +       udf_release_data(pbh);
3398 +
3399 +       if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
3400 +               UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
3401 +       {
3402 +               return NULL;
3403 +       }
3404 +       if ((result = getblk(inode->i_dev, newblock, inode->i_sb->s_blocksize)))
3405 +       {
3406 +               memset(result->b_data, 0x00, inode->i_sb->s_blocksize);
3407 +               mark_buffer_uptodate(result, 1);
3408 +               mark_buffer_dirty(result, 1);
3409 +       }
3410 +       UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
3411 +       UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
3412 +       inode->i_ctime = CURRENT_TIME;
3413 +       UDF_I_UCTIME(inode) = CURRENT_UTIME;
3414 +       inode->i_blocks += inode->i_sb->s_blocksize / 512;
3415 +       if (IS_SYNC(inode))
3416 +               udf_sync_inode(inode);
3417 +       else
3418 +               mark_inode_dirty(inode);
3419 +       return result;
3420 +}
3421 +
3422 +static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
3423 +       long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
3424 +{
3425 +       if ((laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED ||
3426 +               (laarr[*c].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
3427 +       {
3428 +               int curr = *c;
3429 +               int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
3430 +                       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
3431 +               int type = laarr[curr].extLength & ~UDF_EXTENT_LENGTH_MASK;
3432 +
3433 +               if (blen == 1)
3434 +                       ;
3435 +               else if (!offset || blen == offset + 1)
3436 +               {
3437 +                       laarr[curr+2] = laarr[curr+1];
3438 +                       laarr[curr+1] = laarr[curr];
3439 +               }
3440 +               else
3441 +               {
3442 +                       laarr[curr+3] = laarr[curr+1];
3443 +                       laarr[curr+2] = laarr[curr+1] = laarr[curr];
3444 +               }
3445 +
3446 +               if (offset)
3447 +               {
3448 +                       laarr[curr].extLength = type |
3449 +                               (offset << inode->i_sb->s_blocksize_bits);
3450 +                       curr ++;
3451 +                       (*c) ++;
3452 +                       (*endnum) ++;
3453 +               }
3454 +               
3455 +               laarr[curr].extLocation.logicalBlockNum = newblocknum;
3456 +               if ((type >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
3457 +                       laarr[curr].extLocation.partitionReferenceNum =
3458 +                               UDF_I_LOCATION(inode).partitionReferenceNum;
3459 +               laarr[curr].extLength = (EXTENT_RECORDED_ALLOCATED << 30) |
3460 +                       inode->i_sb->s_blocksize;
3461 +               curr ++;
3462 +
3463 +               if (blen != offset + 1)
3464 +               {
3465 +                       if ((type >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
3466 +                               laarr[curr].extLocation.logicalBlockNum += (offset + 1);
3467 +                       laarr[curr].extLength = type |
3468 +                               ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
3469 +                       curr ++;
3470 +                       (*endnum) ++;
3471 +               }
3472 +       }
3473 +}
3474 +
3475 +static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
3476 +        long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
3477 +{
3478 +       int start, length = 0, currlength = 0, i;
3479 +
3480 +       if (*endnum >= (c+1) && !lastblock)
3481 +               return;
3482 +
3483 +       if ((laarr[c+1].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
3484 +       {
3485 +               start = c+1;
3486 +               length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
3487 +                       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
3488 +       }
3489 +       else
3490 +               start = c;
3491 +
3492 +       for (i=start+1; i<=*endnum; i++)
3493 +       {
3494 +               if (i == *endnum)
3495 +               {
3496 +                       if (lastblock)
3497 +                               length += UDF_DEFAULT_PREALLOC_BLOCKS;
3498 +               }
3499 +               else if ((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
3500 +                       length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3501 +                               inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
3502 +               else
3503 +                       break;
3504 +       }
3505 +
3506 +       if (length)
3507 +       {
3508 +               int next = laarr[start].extLocation.logicalBlockNum +
3509 +                       (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
3510 +                       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
3511 +               int numalloc = udf_prealloc_blocks(inode,
3512 +                       laarr[start].extLocation.partitionReferenceNum,
3513 +                       next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
3514 +                               UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
3515 +
3516 +               if (numalloc)
3517 +               {
3518 +                       if (start == (c+1))
3519 +                               laarr[start].extLength +=
3520 +                                       (numalloc << inode->i_sb->s_blocksize_bits);
3521 +                       else
3522 +                       {
3523 +                               memmove(&laarr[c+2], &laarr[c+1],
3524 +                                       sizeof(long_ad) * (*endnum - (c+1)));
3525 +                               (*endnum) ++;
3526 +                               laarr[c+1].extLocation.logicalBlockNum = next;
3527 +                               laarr[c+1].extLocation.partitionReferenceNum =
3528 +                                       laarr[c].extLocation.partitionReferenceNum;
3529 +                               laarr[c+1].extLength = (EXTENT_NOT_RECORDED_ALLOCATED << 30) |
3530 +                                       (numalloc << inode->i_sb->s_blocksize_bits);
3531 +                               start = c+1;
3532 +                       }
3533 +
3534 +                       for (i=start+1; numalloc && i<*endnum; i++)
3535 +                       {
3536 +                               int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3537 +                                       inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
3538 +
3539 +                               if (elen > numalloc)
3540 +                               {
3541 +                                       laarr[c+1].extLength -=
3542 +                                               (numalloc << inode->i_sb->s_blocksize_bits);
3543 +                                       numalloc = 0;
3544 +                               }
3545 +                               else
3546 +                               {
3547 +                                       numalloc -= elen;
3548 +                                       if (*endnum > (i+1))
3549 +                                               memmove(&laarr[i], &laarr[i+1], 
3550 +                                                       sizeof(long_ad) * (*endnum - (i+1)));
3551 +                                       i --;
3552 +                                       (*endnum) --;
3553 +                               }
3554 +                       }
3555 +               }
3556 +       }
3557 +}
3558 +
3559 +static void udf_merge_extents(struct inode *inode,
3560 +        long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
3561 +{
3562 +       int i;
3563 +
3564 +       for (i=0; i<(*endnum-1); i++)
3565 +       {
3566 +               if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
3567 +               {
3568 +                       if (((laarr[i].extLength >> 30) == EXTENT_NOT_RECORDED_NOT_ALLOCATED) ||
3569 +                               ((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
3570 +                               (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3571 +                               inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
3572 +                       {
3573 +                               if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3574 +                                       (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
3575 +                                       inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
3576 +                               {
3577 +                                       laarr[i+1].extLength = (laarr[i+1].extLength -
3578 +                                               (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3579 +                                               UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
3580 +                                       laarr[i].extLength = (UDF_EXTENT_LENGTH_MASK + 1) -
3581 +                                               inode->i_sb->s_blocksize;
3582 +                                       laarr[i+1].extLocation.logicalBlockNum =
3583 +                                               laarr[i].extLocation.logicalBlockNum +
3584 +                                               ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
3585 +                                                       inode->i_sb->s_blocksize_bits);
3586 +                               }
3587 +                               else
3588 +                               {
3589 +                                       laarr[i].extLength = laarr[i+1].extLength +
3590 +                                               (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
3591 +                                               inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
3592 +                                       if (*endnum > (i+2))
3593 +                                               memmove(&laarr[i+1], &laarr[i+2],
3594 +                                                       sizeof(long_ad) * (*endnum - (i+2)));
3595 +                                       i --;
3596 +                                       (*endnum) --;
3597 +                               }
3598 +                       }
3599 +               }
3600 +       }
3601 +}
3602 +
3603 +static void udf_update_extents(struct inode *inode,
3604 +       long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
3605 +       lb_addr pbloc, Uint32 pextoffset, struct buffer_head **pbh)
3606 +{
3607 +       int start = 0, i;
3608 +       lb_addr tmploc;
3609 +       Uint32 tmplen;
3610 +
3611 +       if (startnum > endnum)
3612 +       {
3613 +               for (i=0; i<(startnum-endnum); i++)
3614 +               {
3615 +                       udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
3616 +                               laarr[i].extLength, *pbh);
3617 +               }
3618 +       }
3619 +       else if (startnum < endnum)
3620 +       {
3621 +               for (i=0; i<(endnum-startnum); i++)
3622 +               {
3623 +                       udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
3624 +                               laarr[i].extLength, *pbh);
3625 +                       udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
3626 +                               &laarr[i].extLength, pbh, 1);
3627 +                       start ++;
3628 +               }
3629 +       }
3630 +
3631 +       for (i=start; i<endnum; i++)
3632 +       {
3633 +               udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
3634 +               udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
3635 +                       laarr[i].extLength, *pbh, 1);
3636 +       }
3637 +}
3638 +
3639 +struct buffer_head * udf_bread(struct inode * inode, int block,
3640 +       int create, int * err)
3641 +{
3642 +       struct buffer_head * bh = NULL;
3643 +       int prev_blocks;
3644 +
3645 +       prev_blocks = inode->i_blocks;
3646 +
3647 +       bh = udf_getblk(inode, block, create, err);
3648 +       if (!bh)
3649 +               return NULL;
3650 +
3651 +#if 0
3652 +       if (create &&
3653 +               S_ISDIR(inode->i_mode) &&
3654 +               inode->i_blocks > prev_blocks)
3655 +       {
3656 +               int i;
3657 +               struct buffer_head *tmp_bh = NULL;
3658 +
3659 +               for (i=1;
3660 +                       i < UDF_DEFAULT_PREALLOC_DIR_BLOCKS;
3661 +                       i++)
3662 +               {
3663 +                       tmp_bh = udf_getblk(inode, block+i, create, err);
3664 +                       if (!tmp_bh)
3665 +                       {
3666 +                               udf_release_data(bh);
3667 +                               return 0;
3668 +                       }
3669 +                       udf_release_data(tmp_bh);
3670 +               }
3671 +       }
3672 +#endif
3673 +
3674 +       if (buffer_uptodate(bh))
3675 +               return bh;
3676 +       ll_rw_block(READ, 1, &bh);
3677 +       wait_on_buffer(bh);
3678 +       if (buffer_uptodate(bh))
3679 +               return bh;
3680 +       brelse(bh);
3681 +       *err = -EIO;
3682 +       return NULL;
3683 +}
3684 +
3685 +/*
3686 + * udf_read_inode
3687 + *
3688 + * PURPOSE
3689 + *     Read an inode.
3690 + *
3691 + * DESCRIPTION
3692 + *     This routine is called by iget() [which is called by udf_iget()]
3693 + *      (clean_inode() will have been called first)
3694 + *     when an inode is first read into memory.
3695 + *
3696 + * HISTORY
3697 + *     July 1, 1997 - Andrew E. Mileski
3698 + *     Written, tested, and released.
3699 + *
3700 + * 12/19/98 dgb  Updated to fix size problems.
3701 + */
3702 +void
3703 +udf_read_inode(struct inode *inode)
3704 +{
3705 +       memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(lb_addr));
3706 +}
3707 +
3708 +void
3709 +__udf_read_inode(struct inode *inode)
3710 +{
3711 +       struct buffer_head *bh = NULL;
3712 +       struct FileEntry *fe;
3713 +       Uint16 ident;
3714 +
3715 +       /*
3716 +        * Set defaults, but the inode is still incomplete!
3717 +        * Note: get_new_inode() sets the following on a new inode:
3718 +        *      i_sb = sb
3719 +        *      i_dev = sb->s_dev;
3720 +        *      i_no = ino
3721 +        *      i_flags = sb->s_flags
3722 +        *      i_state = 0
3723 +        * clean_inode(): zero fills and sets
3724 +        *      i_count = 1
3725 +        *      i_nlink = 1
3726 +        *      i_op = NULL;
3727 +        */
3728 +
3729 +       inode->i_blksize = PAGE_SIZE;
3730 +
3731 +       bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
3732 +
3733 +       if (!bh)
3734 +       {
3735 +               printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
3736 +                       inode->i_ino);
3737 +               make_bad_inode(inode);
3738 +               return;
3739 +       }
3740 +
3741 +       if (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY &&
3742 +               ident != TID_UNALLOCATED_SPACE_ENTRY)
3743 +       {
3744 +               printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
3745 +                       inode->i_ino, ident);
3746 +               udf_release_data(bh);
3747 +               make_bad_inode(inode);
3748 +               return;
3749 +       }
3750 +
3751 +       fe = (struct FileEntry *)bh->b_data;
3752 +
3753 +       if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
3754 +       {
3755 +               struct buffer_head *ibh = NULL, *nbh = NULL;
3756 +               struct IndirectEntry *ie;
3757 +
3758 +               ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
3759 +               if (ident == TID_INDIRECT_ENTRY)
3760 +               {
3761 +                       if (ibh)
3762 +                       {
3763 +                               lb_addr loc;
3764 +                               ie = (struct IndirectEntry *)ibh->b_data;
3765 +       
3766 +                               loc = lelb_to_cpu(ie->indirectICB.extLocation);
3767 +       
3768 +                               if (ie->indirectICB.extLength && 
3769 +                                       (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
3770 +                               {
3771 +                                       if (ident == TID_FILE_ENTRY ||
3772 +                                               ident == TID_EXTENDED_FILE_ENTRY)
3773 +                                       {
3774 +                                               memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr));
3775 +                                               udf_release_data(bh);
3776 +                                               udf_release_data(ibh);
3777 +                                               udf_release_data(nbh);
3778 +                                               __udf_read_inode(inode);
3779 +                                               return;
3780 +                                       }
3781 +                                       else
3782 +                                       {
3783 +                                               udf_release_data(nbh);
3784 +                                               udf_release_data(ibh);
3785 +                                       }
3786 +                               }
3787 +                               else
3788 +                                       udf_release_data(ibh);
3789 +                       }
3790 +               }
3791 +               else
3792 +                       udf_release_data(ibh);
3793 +       }
3794 +       else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
3795 +       {
3796 +               printk(KERN_ERR "udf: unsupported strategy type: %d\n",
3797 +                       le16_to_cpu(fe->icbTag.strategyType));
3798 +               udf_release_data(bh);
3799 +               make_bad_inode(inode);
3800 +               return;
3801 +       }
3802 +       udf_fill_inode(inode, bh);
3803 +       udf_release_data(bh);
3804 +}
3805 +
3806 +static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
3807 +{
3808 +       struct FileEntry *fe;
3809 +       struct ExtendedFileEntry *efe;
3810 +       time_t convtime;
3811 +       long convtime_usec;
3812 +       int offset, alen;
3813 +
3814 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
3815 +       inode->i_version = ++event;
3816 +#else
3817 +       inode->i_version = ++global_event;
3818 +#endif
3819 +       UDF_I_NEW_INODE(inode) = 0;
3820 +
3821 +       fe = (struct FileEntry *)bh->b_data;
3822 +       efe = (struct ExtendedFileEntry *)bh->b_data;
3823 +
3824 +       if (le16_to_cpu(fe->icbTag.strategyType) == 4)
3825 +               UDF_I_STRAT4096(inode) = 0;
3826 +       else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
3827 +               UDF_I_STRAT4096(inode) = 1;
3828 +
3829 +       UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICB_FLAG_ALLOC_MASK;
3830 +
3831 +       if (fe->descTag.tagIdent == TID_EXTENDED_FILE_ENTRY)
3832 +               UDF_I_EXTENDED_FE(inode) = 1;
3833 +       else if (fe->descTag.tagIdent == TID_FILE_ENTRY)
3834 +               UDF_I_EXTENDED_FE(inode) = 0;
3835 +       else if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
3836 +       {
3837 +               UDF_I_LENALLOC(inode) =
3838 +                       le32_to_cpu(
3839 +                               ((struct UnallocatedSpaceEntry *)bh->b_data)->lengthAllocDescs);
3840 +               return;
3841 +       }
3842 +
3843 +       inode->i_uid = udf_convert_uid(le32_to_cpu(fe->uid));
3844 +       if ( !inode->i_uid ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
3845 +
3846 +       inode->i_gid = udf_convert_gid(le32_to_cpu(fe->gid));
3847 +       if ( !inode->i_gid ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
3848 +
3849 +       inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
3850 +       if (!inode->i_nlink)
3851 +               inode->i_nlink = 1;
3852 +       
3853 +       inode->i_size = le64_to_cpu(fe->informationLength);
3854 +#if BITS_PER_LONG < 64
3855 +       if (le64_to_cpu(fe->informationLength) & 0xFFFFFFFF00000000ULL)
3856 +               inode->i_size = (Uint32)-1;
3857 +#endif
3858 +
3859 +       inode->i_mode = udf_convert_permissions(fe);
3860 +       inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
3861 +
3862 +       UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
3863 +       UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
3864 +
3865 +       if (UDF_I_EXTENDED_FE(inode) == 0)
3866 +       {
3867 +               inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
3868 +                       (inode->i_sb->s_blocksize_bits - 9);
3869 +
3870 +               if ( udf_stamp_to_time(&convtime, &convtime_usec,
3871 +                       lets_to_cpu(fe->modificationTime)) )
3872 +               {
3873 +                       inode->i_mtime = convtime;
3874 +                       UDF_I_UMTIME(inode) = convtime_usec;
3875 +                       inode->i_ctime = convtime;
3876 +                       UDF_I_UCTIME(inode) = convtime_usec;
3877 +               }
3878 +               else
3879 +               {
3880 +                       inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
3881 +                       UDF_I_UMTIME(inode) = 0;
3882 +                       inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
3883 +                       UDF_I_UCTIME(inode) = 0;
3884 +               }
3885 +
3886 +               if ( udf_stamp_to_time(&convtime, &convtime_usec,
3887 +                       lets_to_cpu(fe->accessTime)) ) 
3888 +               {
3889 +                       inode->i_atime = convtime;
3890 +                       UDF_I_UATIME(inode) = convtime_usec;
3891 +               }
3892 +               else
3893 +               {
3894 +                       inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
3895 +                       UDF_I_UATIME(inode) = convtime_usec;
3896 +               }
3897 +
3898 +               UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
3899 +               UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
3900 +               UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
3901 +               offset = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode);
3902 +               alen = offset + UDF_I_LENALLOC(inode);
3903 +       }
3904 +       else
3905 +       {
3906 +               inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 
3907 +                       (inode->i_sb->s_blocksize_bits - 9);
3908 +
3909 +               if ( udf_stamp_to_time(&convtime, &convtime_usec,
3910 +                       lets_to_cpu(efe->modificationTime)) )
3911 +               {
3912 +                       inode->i_mtime = convtime;
3913 +                       UDF_I_UMTIME(inode) = convtime_usec;
3914 +               }
3915 +               else
3916 +               {
3917 +                       inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
3918 +                       UDF_I_UMTIME(inode) = 0;
3919 +               }
3920 +
3921 +               if ( udf_stamp_to_time(&convtime, &convtime_usec,
3922 +                       lets_to_cpu(efe->accessTime)) )
3923 +               {
3924 +                       inode->i_atime = convtime;
3925 +                       UDF_I_UATIME(inode) = convtime_usec;
3926 +               }
3927 +               else
3928 +               {
3929 +                       inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
3930 +                       UDF_I_UATIME(inode) = 0;
3931 +               }
3932 +
3933 +               if ( udf_stamp_to_time(&convtime, &convtime_usec,
3934 +                       lets_to_cpu(efe->createTime)) )
3935 +               {
3936 +                       inode->i_ctime = convtime;
3937 +                       UDF_I_UCTIME(inode) = convtime_usec;
3938 +               }
3939 +               else
3940 +               {
3941 +                       inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
3942 +                       UDF_I_UCTIME(inode) = 0;
3943 +               }
3944 +
3945 +               UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
3946 +               UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
3947 +               UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
3948 +               offset = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode);
3949 +               alen = offset + UDF_I_LENALLOC(inode);
3950 +       }
3951 +
3952 +       switch (fe->icbTag.fileType)
3953 +       {
3954 +               case FILE_TYPE_DIRECTORY:
3955 +               {
3956 +                       inode->i_op = &udf_dir_inode_operations;
3957 +                       inode->i_mode |= S_IFDIR;
3958 +                       inode->i_nlink ++;
3959 +                       break;
3960 +               }
3961 +               case FILE_TYPE_REGULAR:
3962 +               case FILE_TYPE_NONE:
3963 +               {
3964 +                       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
3965 +                               inode->i_op = &udf_file_inode_operations_adinicb;
3966 +                       else
3967 +                               inode->i_op = &udf_file_inode_operations;
3968 +                       inode->i_mode |= S_IFREG;
3969 +                       break;
3970 +               }
3971 +               case FILE_TYPE_BLOCK:
3972 +               {
3973 +                       inode->i_op = &blkdev_inode_operations;
3974 +                       inode->i_mode |= S_IFBLK;
3975 +                       break;
3976 +               }
3977 +               case FILE_TYPE_CHAR:
3978 +               {
3979 +                       inode->i_op = &chrdev_inode_operations;
3980 +                       inode->i_mode |= S_IFCHR;
3981 +                       break;
3982 +               }
3983 +               case FILE_TYPE_FIFO:
3984 +               {
3985 +                       init_fifo(inode);
3986 +                       break;
3987 +               }
3988 +               case FILE_TYPE_SYMLINK:
3989 +               {
3990 +                       /* untested! */
3991 +                       inode->i_op = &udf_symlink_inode_operations;
3992 +                       inode->i_mode = S_IFLNK|S_IRWXUGO;
3993 +                       break;
3994 +               }
3995 +               default:
3996 +               {
3997 +                       printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
3998 +                               inode->i_ino, fe->icbTag.fileType);
3999 +                       make_bad_inode(inode);
4000 +                       return;
4001 +               }
4002 +       }
4003 +       if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
4004 +       {
4005 +               struct buffer_head *tbh = NULL;
4006 +               struct DeviceSpecificationExtendedAttr *dsea =
4007 +                       (struct DeviceSpecificationExtendedAttr *)
4008 +                               udf_get_extendedattr(inode, 12, 1, &tbh);
4009 +
4010 +               if (dsea)
4011 +               {
4012 +                       inode->i_rdev = to_kdev_t(
4013 +                               (le32_to_cpu(dsea->majorDeviceIdent)) << 8) |
4014 +                               (le32_to_cpu(dsea->minorDeviceIdent) & 0xFF);
4015 +                       /* Developer ID ??? */
4016 +                       udf_release_data(tbh);
4017 +               }
4018 +               else
4019 +               {
4020 +                       make_bad_inode(inode);
4021 +               }
4022 +       }
4023 +}
4024 +
4025 +static mode_t
4026 +udf_convert_permissions(struct FileEntry *fe)
4027 +{
4028 +       mode_t mode;
4029 +       Uint32 permissions;
4030 +       Uint32 flags;
4031 +
4032 +       permissions = le32_to_cpu(fe->permissions);
4033 +       flags = le16_to_cpu(fe->icbTag.flags);
4034 +
4035 +       mode =  (( permissions      ) & S_IRWXO) |
4036 +                       (( permissions >> 2 ) & S_IRWXG) |
4037 +                       (( permissions >> 4 ) & S_IRWXU) |
4038 +                       (( flags & ICB_FLAG_SETUID) ? S_ISUID : 0) |
4039 +                       (( flags & ICB_FLAG_SETGID) ? S_ISGID : 0) |
4040 +                       (( flags & ICB_FLAG_STICKY) ? S_ISVTX : 0);
4041 +
4042 +       return mode;
4043 +}
4044 +
4045 +/*
4046 + * udf_write_inode
4047 + *
4048 + * PURPOSE
4049 + *     Write out the specified inode.
4050 + *
4051 + * DESCRIPTION
4052 + *     This routine is called whenever an inode is synced.
4053 + *     Currently this routine is just a placeholder.
4054 + *
4055 + * HISTORY
4056 + *     July 1, 1997 - Andrew E. Mileski
4057 + *     Written, tested, and released.
4058 + */
4059 +
4060 +void udf_write_inode(struct inode * inode)
4061 +{
4062 +       udf_update_inode(inode, 0);
4063 +}
4064 +
4065 +int udf_sync_inode(struct inode * inode)
4066 +{
4067 +       return udf_update_inode(inode, 1);
4068 +}
4069 +
4070 +static int
4071 +udf_update_inode(struct inode *inode, int do_sync)
4072 +{
4073 +       struct buffer_head *bh = NULL;
4074 +       struct FileEntry *fe;
4075 +       struct ExtendedFileEntry *efe;
4076 +       Uint32 udfperms;
4077 +       Uint16 icbflags;
4078 +       Uint16 crclen;
4079 +       int i;
4080 +       timestamp cpu_time;
4081 +       int err = 0;
4082 +
4083 +       bh = udf_tread(inode->i_sb,
4084 +                       udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
4085 +                       inode->i_sb->s_blocksize);
4086 +       if (!bh)
4087 +       {
4088 +               udf_debug("bread failure\n");
4089 +               return -EIO;
4090 +       }
4091 +       fe = (struct FileEntry *)bh->b_data;
4092 +       efe = (struct ExtendedFileEntry *)bh->b_data;
4093 +       if (UDF_I_NEW_INODE(inode) == 1)
4094 +       {
4095 +               if (UDF_I_EXTENDED_FE(inode) == 0)
4096 +                       memset(bh->b_data, 0x0, sizeof(struct FileEntry));
4097 +               else
4098 +                       memset(bh->b_data, 0x00, sizeof(struct ExtendedFileEntry));
4099 +               memset(bh->b_data + udf_file_entry_alloc_offset(inode) +
4100 +                       UDF_I_LENALLOC(inode), 0x0, inode->i_sb->s_blocksize -
4101 +                       udf_file_entry_alloc_offset(inode) - UDF_I_LENALLOC(inode));
4102 +               UDF_I_NEW_INODE(inode) = 0;
4103 +       }
4104 +
4105 +       if (fe->descTag.tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
4106 +       {
4107 +               struct UnallocatedSpaceEntry *use =
4108 +                       (struct UnallocatedSpaceEntry *)bh->b_data;
4109 +
4110 +               use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
4111 +               crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) -
4112 +                       sizeof(tag);
4113 +               use->descTag.descCRCLength = cpu_to_le16(crclen);
4114 +               use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
4115 +
4116 +               use->descTag.tagChecksum = 0;
4117 +               for (i=0; i<16; i++)
4118 +                       if (i != 4)
4119 +                               use->descTag.tagChecksum += ((Uint8 *)&(use->descTag))[i];
4120 +
4121 +               mark_buffer_dirty(bh, 1);
4122 +               udf_release_data(bh);
4123 +               return err;
4124 +       }
4125 +
4126 +       if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
4127 +               fe->uid = cpu_to_le32(inode->i_uid);
4128 +
4129 +       if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
4130 +               fe->gid = cpu_to_le32(inode->i_gid);
4131 +
4132 +       udfperms =  ((inode->i_mode & S_IRWXO)     ) |
4133 +                               ((inode->i_mode & S_IRWXG) << 2) |
4134 +                               ((inode->i_mode & S_IRWXU) << 4);
4135 +
4136 +       udfperms |= (le32_to_cpu(fe->permissions) &
4137 +               (PERM_O_DELETE | PERM_O_CHATTR |
4138 +                PERM_G_DELETE | PERM_G_CHATTR |
4139 +                PERM_U_DELETE | PERM_U_CHATTR));
4140 +       fe->permissions = cpu_to_le32(udfperms);
4141 +
4142 +       if (S_ISDIR(inode->i_mode))
4143 +               fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
4144 +       else
4145 +               fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
4146 +
4147 +       fe->informationLength = cpu_to_le64(inode->i_size);
4148 +
4149 +       if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
4150 +       {
4151 +               EntityID *eid;
4152 +               struct buffer_head *tbh = NULL;
4153 +               struct DeviceSpecificationExtendedAttr *dsea =
4154 +                       (struct DeviceSpecificationExtendedAttr *)
4155 +                               udf_get_extendedattr(inode, 12, 1, &tbh);       
4156 +
4157 +               if (!dsea)
4158 +               {
4159 +                       dsea = (struct DeviceSpecificationExtendedAttr *)
4160 +                               udf_add_extendedattr(inode,
4161 +                                       sizeof(struct DeviceSpecificationExtendedAttr) +
4162 +                                       sizeof(EntityID), 12, 0x3, &tbh);
4163 +                       dsea->attrType = 12;
4164 +                       dsea->attrSubtype = 1;
4165 +                       dsea->attrLength = sizeof(struct DeviceSpecificationExtendedAttr) +
4166 +                               sizeof(EntityID);
4167 +                       dsea->impUseLength = sizeof(EntityID);
4168 +               }
4169 +               eid = (EntityID *)dsea->impUse;
4170 +               memset(eid, 0, sizeof(EntityID));
4171 +               strcpy(eid->ident, UDF_ID_DEVELOPER);
4172 +               eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
4173 +               eid->identSuffix[1] = UDF_OS_ID_LINUX;
4174 +               dsea->majorDeviceIdent = kdev_t_to_nr(inode->i_rdev) >> 8;
4175 +               dsea->minorDeviceIdent = kdev_t_to_nr(inode->i_rdev) & 0xFF;
4176 +               mark_buffer_dirty(tbh, 1);
4177 +               udf_release_data(tbh);
4178 +       }
4179 +
4180 +       if (UDF_I_EXTENDED_FE(inode) == 0)
4181 +       {
4182 +               fe->logicalBlocksRecorded = cpu_to_le64(
4183 +                       (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
4184 +                       (inode->i_sb->s_blocksize_bits - 9));
4185 +
4186 +               if (udf_time_to_stamp(&cpu_time, inode->i_atime, UDF_I_UATIME(inode)))
4187 +                       fe->accessTime = cpu_to_lets(cpu_time);
4188 +               if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode)))
4189 +                       fe->modificationTime = cpu_to_lets(cpu_time);
4190 +               memset(&(fe->impIdent), 0, sizeof(EntityID));
4191 +               strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
4192 +               fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
4193 +               fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
4194 +               fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
4195 +               fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
4196 +               fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
4197 +               fe->descTag.tagIdent = le16_to_cpu(TID_FILE_ENTRY);
4198 +               crclen = sizeof(struct FileEntry);
4199 +       }
4200 +       else
4201 +       {
4202 +               efe->logicalBlocksRecorded = cpu_to_le64(
4203 +                       (inode->i_blocks + (2 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
4204 +                       (inode->i_sb->s_blocksize_bits - 9));
4205 +
4206 +               if (udf_time_to_stamp(&cpu_time, inode->i_atime, UDF_I_UATIME(inode)))
4207 +                       efe->accessTime = cpu_to_lets(cpu_time);
4208 +               if (udf_time_to_stamp(&cpu_time, inode->i_mtime, UDF_I_UMTIME(inode)))
4209 +                       efe->modificationTime = cpu_to_lets(cpu_time);
4210 +               if (udf_time_to_stamp(&cpu_time, inode->i_ctime, UDF_I_UCTIME(inode)))
4211 +                       efe->createTime = cpu_to_lets(cpu_time);
4212 +               memset(&(efe->impIdent), 0, sizeof(EntityID));
4213 +               strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
4214 +               efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
4215 +               efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
4216 +               efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
4217 +               efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
4218 +               efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
4219 +               efe->descTag.tagIdent = le16_to_cpu(TID_EXTENDED_FILE_ENTRY);
4220 +               crclen = sizeof(struct ExtendedFileEntry);
4221 +       }
4222 +       if (UDF_I_STRAT4096(inode))
4223 +       {
4224 +               fe->icbTag.strategyType = cpu_to_le16(4096);
4225 +               fe->icbTag.strategyParameter = cpu_to_le16(1);
4226 +               fe->icbTag.numEntries = cpu_to_le16(2);
4227 +       }
4228 +       else
4229 +       {
4230 +               fe->icbTag.strategyType = cpu_to_le16(4);
4231 +               fe->icbTag.numEntries = cpu_to_le16(1);
4232 +       }
4233 +
4234 +       if (S_ISDIR(inode->i_mode))
4235 +               fe->icbTag.fileType = FILE_TYPE_DIRECTORY;
4236 +       else if (S_ISREG(inode->i_mode))
4237 +               fe->icbTag.fileType = FILE_TYPE_REGULAR;
4238 +       else if (S_ISLNK(inode->i_mode))
4239 +               fe->icbTag.fileType = FILE_TYPE_SYMLINK;
4240 +       else if (S_ISBLK(inode->i_mode))
4241 +               fe->icbTag.fileType = FILE_TYPE_BLOCK;
4242 +       else if (S_ISCHR(inode->i_mode))
4243 +               fe->icbTag.fileType = FILE_TYPE_CHAR;
4244 +       else if (S_ISFIFO(inode->i_mode))
4245 +               fe->icbTag.fileType = FILE_TYPE_FIFO;
4246 +
4247 +       icbflags = UDF_I_ALLOCTYPE(inode) |
4248 +                       ((inode->i_mode & S_ISUID) ? ICB_FLAG_SETUID : 0) |
4249 +                       ((inode->i_mode & S_ISGID) ? ICB_FLAG_SETGID : 0) |
4250 +                       ((inode->i_mode & S_ISVTX) ? ICB_FLAG_STICKY : 0) |
4251 +                       (le16_to_cpu(fe->icbTag.flags) &
4252 +                               ~(ICB_FLAG_ALLOC_MASK | ICB_FLAG_SETUID |
4253 +                               ICB_FLAG_SETGID | ICB_FLAG_STICKY));
4254 +
4255 +       fe->icbTag.flags = cpu_to_le16(icbflags);
4256 +       fe->descTag.descVersion = cpu_to_le16(2);
4257 +       fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
4258 +       fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
4259 +       crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
4260 +       fe->descTag.descCRCLength = cpu_to_le16(crclen);
4261 +       fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
4262 +
4263 +       fe->descTag.tagChecksum = 0;
4264 +       for (i=0; i<16; i++)
4265 +               if (i != 4)
4266 +                       fe->descTag.tagChecksum += ((Uint8 *)&(fe->descTag))[i];
4267 +
4268 +       /* write the data blocks */
4269 +       mark_buffer_dirty(bh, 1);
4270 +       if (do_sync)
4271 +       {
4272 +               ll_rw_block(WRITE, 1, &bh);
4273 +               wait_on_buffer(bh);
4274 +               if (buffer_req(bh) && !buffer_uptodate(bh))
4275 +               {
4276 +                       printk("IO error syncing udf inode [%s:%08lx]\n",
4277 +                               bdevname(inode->i_dev), inode->i_ino);
4278 +                       err = -EIO;
4279 +               }
4280 +       }
4281 +       udf_release_data(bh);
4282 +       return err;
4283 +}
4284 +
4285 +/*
4286 + * udf_iget
4287 + *
4288 + * PURPOSE
4289 + *     Get an inode.
4290 + *
4291 + * DESCRIPTION
4292 + *     This routine replaces iget() and read_inode().
4293 + *
4294 + * HISTORY
4295 + *     October 3, 1997 - Andrew E. Mileski
4296 + *     Written, tested, and released.
4297 + *
4298 + * 12/19/98 dgb  Added semaphore and changed to be a wrapper of iget
4299 + */
4300 +struct inode *
4301 +udf_iget(struct super_block *sb, lb_addr ino)
4302 +{
4303 +       struct inode *inode;
4304 +       unsigned long block;
4305 +
4306 +       block = udf_get_lb_pblock(sb, ino, 0);
4307 +
4308 +       /* Get the inode */
4309 +
4310 +       inode = iget(sb, block);
4311 +               /* calls udf_read_inode() ! */
4312 +
4313 +       if (!inode)
4314 +       {
4315 +               printk(KERN_ERR "udf: iget() failed\n");
4316 +               return NULL;
4317 +       }
4318 +       else if (is_bad_inode(inode))
4319 +       {
4320 +               iput(inode);
4321 +               return NULL;
4322 +       }
4323 +       else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF &&
4324 +               UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF)
4325 +       {
4326 +               memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr));
4327 +               __udf_read_inode(inode);
4328 +       }
4329 +
4330 +       if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
4331 +       {
4332 +               udf_debug("block=%d, partition=%d out of range\n",
4333 +                       ino.logicalBlockNum, ino.partitionReferenceNum);
4334 +               return NULL;
4335 +       }
4336 +
4337 +       return inode;
4338 +}
4339 +
4340 +int udf_add_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
4341 +       lb_addr eloc, Uint32 elen, struct buffer_head **bh, int inc)
4342 +{
4343 +       int adsize;
4344 +       short_ad *sad = NULL;
4345 +       long_ad *lad = NULL;
4346 +       struct AllocExtDesc *aed;
4347 +       int ret;
4348 +
4349 +       if (!(*bh))
4350 +       {
4351 +               if (!(*bh = udf_tread(inode->i_sb,
4352 +                       udf_get_lb_pblock(inode->i_sb, *bloc, 0),
4353 +                       inode->i_sb->s_blocksize)))
4354 +               {
4355 +                       udf_debug("reading block %d failed!\n",
4356 +                               udf_get_lb_pblock(inode->i_sb, *bloc, 0));
4357 +                       return -1;
4358 +               }
4359 +       }
4360 +
4361 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
4362 +               adsize = sizeof(short_ad);
4363 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
4364 +               adsize = sizeof(long_ad);
4365 +       else
4366 +               return -1;
4367 +
4368 +       if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
4369 +       {
4370 +               char *sptr, *dptr;
4371 +               struct buffer_head *nbh;
4372 +               int err, loffset;
4373 +               lb_addr obloc = *bloc;
4374 +
4375 +               if (!(bloc->logicalBlockNum = udf_new_block(inode,
4376 +                       obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
4377 +               {
4378 +                       return -1;
4379 +               }
4380 +               if (!(nbh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
4381 +                       *bloc, 0), inode->i_sb->s_blocksize)))
4382 +               {
4383 +                       return -1;
4384 +               }
4385 +               aed = (struct AllocExtDesc *)(nbh->b_data);
4386 +               aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
4387 +               if (*extoffset + adsize > inode->i_sb->s_blocksize)
4388 +               {
4389 +                       loffset = *extoffset;
4390 +                       aed->lengthAllocDescs = cpu_to_le32(adsize);
4391 +                       sptr = (*bh)->b_data + *extoffset - adsize;
4392 +                       dptr = nbh->b_data + sizeof(struct AllocExtDesc);
4393 +                       memcpy(dptr, sptr, adsize);
4394 +                       *extoffset = sizeof(struct AllocExtDesc) + adsize;
4395 +               }
4396 +               else
4397 +               {
4398 +                       loffset = *extoffset + adsize;
4399 +                       aed->lengthAllocDescs = cpu_to_le32(0);
4400 +                       sptr = (*bh)->b_data + *extoffset;
4401 +                       *extoffset = sizeof(struct AllocExtDesc);
4402 +
4403 +                       if (memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
4404 +                       {
4405 +                               aed = (struct AllocExtDesc *)(*bh)->b_data;
4406 +                               aed->lengthAllocDescs =
4407 +                                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
4408 +                       }
4409 +                       else
4410 +                       {
4411 +                               UDF_I_LENALLOC(inode) += adsize;
4412 +                               mark_inode_dirty(inode);
4413 +                       }
4414 +               }
4415 +               udf_new_tag(nbh->b_data, TID_ALLOC_EXTENT_DESC, 2, 1,
4416 +                       bloc->logicalBlockNum, sizeof(tag));
4417 +               switch (UDF_I_ALLOCTYPE(inode))
4418 +               {
4419 +                       case ICB_FLAG_AD_SHORT:
4420 +                       {
4421 +                               sad = (short_ad *)sptr;
4422 +                               sad->extLength = cpu_to_le32(
4423 +                                       EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
4424 +                                       inode->i_sb->s_blocksize);
4425 +                               sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
4426 +                               break;
4427 +                       }
4428 +                       case ICB_FLAG_AD_LONG:
4429 +                       {
4430 +                               lad = (long_ad *)sptr;
4431 +                               lad->extLength = cpu_to_le32(
4432 +                                       EXTENT_NEXT_EXTENT_ALLOCDECS << 30 |
4433 +                                       inode->i_sb->s_blocksize);
4434 +                               lad->extLocation = cpu_to_lelb(*bloc);
4435 +                               break;
4436 +                       }
4437 +               }
4438 +               udf_update_tag((*bh)->b_data, loffset);
4439 +               mark_buffer_dirty(*bh, 1);
4440 +               udf_release_data(*bh);
4441 +               *bh = nbh;
4442 +       }
4443 +
4444 +       ret = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
4445 +
4446 +       if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
4447 +       {
4448 +               UDF_I_LENALLOC(inode) += adsize;
4449 +               mark_inode_dirty(inode);
4450 +       }
4451 +       else
4452 +       {
4453 +               aed = (struct AllocExtDesc *)(*bh)->b_data;
4454 +               aed->lengthAllocDescs =
4455 +                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
4456 +               udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
4457 +               mark_buffer_dirty(*bh, 1);
4458 +       }
4459 +
4460 +       return ret;
4461 +}
4462 +
4463 +int udf_write_aext(struct inode *inode, lb_addr bloc, int *extoffset,
4464 +    lb_addr eloc, Uint32 elen, struct buffer_head *bh, int inc)
4465 +{
4466 +       int adsize;
4467 +       short_ad *sad = NULL;
4468 +       long_ad *lad = NULL;
4469 +
4470 +       if (!(bh))
4471 +       {
4472 +               if (!(bh = udf_tread(inode->i_sb,
4473 +                       udf_get_lb_pblock(inode->i_sb, bloc, 0),
4474 +                       inode->i_sb->s_blocksize)))
4475 +               {
4476 +                       udf_debug("reading block %d failed!\n",
4477 +                               udf_get_lb_pblock(inode->i_sb, bloc, 0));
4478 +                       return -1;
4479 +               }
4480 +       }
4481 +       else
4482 +               bh->b_count ++;
4483 +
4484 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
4485 +               adsize = sizeof(short_ad);
4486 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
4487 +               adsize = sizeof(long_ad);
4488 +       else
4489 +               return -1;
4490 +
4491 +       switch (UDF_I_ALLOCTYPE(inode))
4492 +       {
4493 +               case ICB_FLAG_AD_SHORT:
4494 +               {
4495 +                       sad = (short_ad *)((bh)->b_data + *extoffset);
4496 +                       sad->extLength = cpu_to_le32(elen);
4497 +                       sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
4498 +                       break;
4499 +               }
4500 +               case ICB_FLAG_AD_LONG:
4501 +               {
4502 +                       lad = (long_ad *)((bh)->b_data + *extoffset);
4503 +                       lad->extLength = cpu_to_le32(elen);
4504 +                       lad->extLocation = cpu_to_lelb(eloc);
4505 +                       break;
4506 +               }
4507 +       }
4508 +
4509 +       if (memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
4510 +       {
4511 +               struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh)->b_data;
4512 +               udf_update_tag((bh)->b_data,
4513 +                       le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct AllocExtDesc));
4514 +       }
4515 +       else
4516 +               mark_inode_dirty(inode);
4517 +
4518 +       mark_buffer_dirty(bh, 1);
4519 +
4520 +       if (inc)
4521 +               *extoffset += adsize;
4522 +       udf_release_data(bh);
4523 +       return (elen >> 30);
4524 +}
4525 +
4526 +int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
4527 +       lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
4528 +{
4529 +       Uint16 tagIdent;
4530 +       int pos, alen;
4531 +       Uint8 etype;
4532 +
4533 +       if (!(*bh))
4534 +       {
4535 +               if (!(*bh = udf_tread(inode->i_sb,
4536 +                       udf_get_lb_pblock(inode->i_sb, *bloc, 0),
4537 +                       inode->i_sb->s_blocksize)))
4538 +               {
4539 +                       udf_debug("reading block %d failed!\n",
4540 +                               udf_get_lb_pblock(inode->i_sb, *bloc, 0));
4541 +                       return -1;
4542 +               }
4543 +       }
4544 +
4545 +       tagIdent = ((tag *)(*bh)->b_data)->tagIdent;
4546 +
4547 +       if (tagIdent == TID_FILE_ENTRY || tagIdent == TID_EXTENDED_FILE_ENTRY ||
4548 +               UDF_I_NEW_INODE(inode))
4549 +       {
4550 +               pos = udf_file_entry_alloc_offset(inode);
4551 +               alen = UDF_I_LENALLOC(inode) + pos;
4552 +       }
4553 +       else if (tagIdent == TID_UNALLOCATED_SPACE_ENTRY)
4554 +       {
4555 +               pos = sizeof(struct UnallocatedSpaceEntry);
4556 +               alen = UDF_I_LENALLOC(inode) + pos;
4557 +       }
4558 +       else if (tagIdent == TID_ALLOC_EXTENT_DESC)
4559 +       {
4560 +               struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
4561 +
4562 +               pos = sizeof(struct AllocExtDesc);
4563 +               alen = le32_to_cpu(aed->lengthAllocDescs) + pos;
4564 +       }
4565 +       else
4566 +               return -1;
4567 +
4568 +       if (!(*extoffset))
4569 +               *extoffset = pos;
4570 +
4571 +       switch (UDF_I_ALLOCTYPE(inode))
4572 +       {
4573 +               case ICB_FLAG_AD_SHORT:
4574 +               {
4575 +                       short_ad *sad;
4576 +
4577 +                       if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc)))
4578 +                               return -1;
4579 +
4580 +                       if ((etype = le32_to_cpu(sad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)
4581 +                       {
4582 +                               bloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
4583 +                               *extoffset = 0;
4584 +                               udf_release_data(*bh);
4585 +                               *bh = NULL;
4586 +                               return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc);
4587 +                       }
4588 +                       else
4589 +                       {
4590 +                               eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
4591 +                               eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
4592 +                               *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
4593 +                       }
4594 +                       break;
4595 +               }
4596 +               case ICB_FLAG_AD_LONG:
4597 +               {
4598 +                       long_ad *lad;
4599 +
4600 +                       if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc)))
4601 +                               return -1;
4602 +
4603 +                       if ((etype = le32_to_cpu(lad->extLength) >> 30) == EXTENT_NEXT_EXTENT_ALLOCDECS)
4604 +                       {
4605 +                               *bloc = lelb_to_cpu(lad->extLocation);
4606 +                               *extoffset = 0;
4607 +                               udf_release_data(*bh);
4608 +                               *bh = NULL;
4609 +                               return udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, inc);
4610 +                       }
4611 +                       else
4612 +                       {
4613 +                               *eloc = lelb_to_cpu(lad->extLocation);
4614 +                               *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
4615 +                       }
4616 +                       break;
4617 +               }
4618 +               case ICB_FLAG_AD_IN_ICB:
4619 +               {
4620 +                       if (UDF_I_LENALLOC(inode) == 0)
4621 +                               return -1;
4622 +                       etype = EXTENT_RECORDED_ALLOCATED;
4623 +                       *eloc = UDF_I_LOCATION(inode);
4624 +                       *elen = UDF_I_LENALLOC(inode);
4625 +                       break;
4626 +               }
4627 +               default:
4628 +               {
4629 +                       udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
4630 +                       return -1;
4631 +               }
4632 +       }
4633 +       if (*elen)
4634 +               return etype;
4635 +
4636 +       udf_debug("Empty Extent, inode=%ld, alloctype=%d, eloc=%d, elen=%d, etype=%d, extoffset=%d\n",
4637 +               inode->i_ino, UDF_I_ALLOCTYPE(inode), eloc->logicalBlockNum, *elen, etype, *extoffset);
4638 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
4639 +               *extoffset -= sizeof(short_ad);
4640 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
4641 +               *extoffset -= sizeof(long_ad);
4642 +       return -1;
4643 +}
4644 +
4645 +int udf_current_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
4646 +       lb_addr *eloc, Uint32 *elen, struct buffer_head **bh, int inc)
4647 +{
4648 +       int pos, alen;
4649 +       Uint8 etype;
4650 +
4651 +       if (!(*bh))
4652 +       {
4653 +               if (!(*bh = udf_tread(inode->i_sb,
4654 +                       udf_get_lb_pblock(inode->i_sb, *bloc, 0),
4655 +                       inode->i_sb->s_blocksize)))
4656 +               {
4657 +                       udf_debug("reading block %d failed!\n",
4658 +                               udf_get_lb_pblock(inode->i_sb, *bloc, 0));
4659 +                       return -1;
4660 +               }
4661 +               udf_debug("new bh, count=%d\n", (*bh)->b_count);
4662 +       }
4663 +
4664 +       if (!memcmp(&UDF_I_LOCATION(inode), bloc, sizeof(lb_addr)))
4665 +       {
4666 +               if (!(UDF_I_EXTENDED_FE(inode)))
4667 +                       pos = sizeof(struct FileEntry) + UDF_I_LENEATTR(inode);
4668 +               else
4669 +                       pos = sizeof(struct ExtendedFileEntry) + UDF_I_LENEATTR(inode);
4670 +               alen = UDF_I_LENALLOC(inode) + pos;
4671 +       }
4672 +       else
4673 +       {
4674 +               struct AllocExtDesc *aed = (struct AllocExtDesc *)(*bh)->b_data;
4675 +
4676 +               pos = sizeof(struct AllocExtDesc);
4677 +               alen = le32_to_cpu(aed->lengthAllocDescs) + pos;
4678 +       }
4679 +
4680 +       if (!(*extoffset))
4681 +               *extoffset = pos;
4682 +
4683 +       switch (UDF_I_ALLOCTYPE(inode))
4684 +       {
4685 +               case ICB_FLAG_AD_SHORT:
4686 +               {
4687 +                       short_ad *sad;
4688 +
4689 +                       if (!(sad = udf_get_fileshortad((*bh)->b_data, alen, extoffset, inc)))
4690 +                               return -1;
4691 +
4692 +                       etype = le32_to_cpu(sad->extLength) >> 30;
4693 +                       eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
4694 +                       eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
4695 +                       *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
4696 +                       break;
4697 +               }
4698 +               case ICB_FLAG_AD_LONG:
4699 +               {
4700 +                       long_ad *lad;
4701 +
4702 +                       if (!(lad = udf_get_filelongad((*bh)->b_data, alen, extoffset, inc)))
4703 +                               return -1;
4704 +
4705 +                       etype = le32_to_cpu(lad->extLength) >> 30;
4706 +                       *eloc = lelb_to_cpu(lad->extLocation);
4707 +                       *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
4708 +                       break;
4709 +               }
4710 +               default:
4711 +               {
4712 +                       udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
4713 +                       return -1;
4714 +               }
4715 +       }
4716 +       if (*elen)
4717 +               return etype;
4718 +
4719 +       udf_debug("Empty Extent!\n");
4720 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
4721 +               *extoffset -= sizeof(short_ad);
4722 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
4723 +               *extoffset -= sizeof(long_ad);
4724 +       return -1;
4725 +}
4726 +
4727 +int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
4728 +    lb_addr neloc, Uint32 nelen, struct buffer_head *bh)
4729 +{
4730 +       lb_addr oeloc;
4731 +       Uint32 oelen;
4732 +       int type;
4733 +
4734 +       if (!bh)
4735 +       {
4736 +               if (!(bh = udf_tread(inode->i_sb,
4737 +                       udf_get_lb_pblock(inode->i_sb, bloc, 0),
4738 +                       inode->i_sb->s_blocksize)))
4739 +               {
4740 +                       udf_debug("reading block %d failed!\n",
4741 +                               udf_get_lb_pblock(inode->i_sb, bloc, 0));
4742 +                       return -1;
4743 +               }
4744 +       }
4745 +       else
4746 +               bh->b_count ++;
4747 +
4748 +       while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
4749 +       {
4750 +               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
4751 +
4752 +               neloc = oeloc;
4753 +               nelen = (type << 30) | oelen;
4754 +       }
4755 +       udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
4756 +       udf_release_data(bh);
4757 +       return (nelen >> 30);
4758 +}
4759 +
4760 +int udf_delete_aext(struct inode *inode, lb_addr nbloc, int nextoffset,
4761 +       lb_addr eloc, Uint32 elen, struct buffer_head *nbh)
4762 +{
4763 +       struct buffer_head *obh;
4764 +       lb_addr obloc;
4765 +       int oextoffset, adsize;
4766 +       char type;
4767 +       struct AllocExtDesc *aed;
4768 +
4769 +       if (!(nbh))
4770 +       {
4771 +               if (!(nbh = udf_tread(inode->i_sb,
4772 +                       udf_get_lb_pblock(inode->i_sb, nbloc, 0),
4773 +                       inode->i_sb->s_blocksize)))
4774 +               {
4775 +                       udf_debug("reading block %d failed!\n",
4776 +                               udf_get_lb_pblock(inode->i_sb, nbloc, 0));
4777 +                       return -1;
4778 +               }
4779 +       }
4780 +       else
4781 +               nbh->b_count ++;
4782 +       nbh->b_count ++;
4783 +
4784 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
4785 +               adsize = sizeof(short_ad);
4786 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
4787 +               adsize = sizeof(long_ad);
4788 +       else
4789 +               adsize = 0;
4790 +
4791 +       obh = nbh;
4792 +       obloc = nbloc;
4793 +       oextoffset = nextoffset;
4794 +
4795 +       if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
4796 +               return -1;
4797 +
4798 +       while ((type = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
4799 +       {
4800 +               udf_write_aext(inode, obloc, &oextoffset, eloc, (type << 30) | elen, obh, 1);
4801 +               if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
4802 +               {
4803 +                       obloc = nbloc;
4804 +                       udf_release_data(obh);
4805 +                       nbh->b_count ++;
4806 +                       obh = nbh;
4807 +                       oextoffset = nextoffset - adsize;
4808 +               }
4809 +       }
4810 +       memset(&eloc, 0x00, sizeof(lb_addr));
4811 +       elen = 0;
4812 +
4813 +       if (memcmp(&nbloc, &obloc, sizeof(lb_addr)))
4814 +       {
4815 +               udf_free_blocks(inode, nbloc, 0, 1);
4816 +               udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
4817 +               udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
4818 +               if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
4819 +               {
4820 +                       UDF_I_LENALLOC(inode) -= (adsize * 2);
4821 +                       mark_inode_dirty(inode);
4822 +               }
4823 +               else
4824 +               {
4825 +                       aed = (struct AllocExtDesc *)(obh)->b_data;
4826 +                       aed->lengthAllocDescs =
4827 +                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
4828 +                       udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
4829 +                       mark_buffer_dirty(obh, 1);
4830 +               }
4831 +       }
4832 +       else
4833 +       {
4834 +               udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
4835 +               if (!memcmp(&UDF_I_LOCATION(inode), &obloc, sizeof(lb_addr)))
4836 +               {
4837 +                       UDF_I_LENALLOC(inode) -= adsize;
4838 +                       mark_inode_dirty(inode);
4839 +               }
4840 +               else
4841 +               {
4842 +                       aed = (struct AllocExtDesc *)(obh)->b_data;
4843 +                       aed->lengthAllocDescs =
4844 +                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
4845 +                       udf_update_tag((obh)->b_data, oextoffset - adsize);
4846 +                       mark_buffer_dirty(obh, 1);
4847 +               }
4848 +       }
4849 +       
4850 +       udf_release_data(nbh);
4851 +       udf_release_data(obh);
4852 +       return (elen >> 30);
4853 +}
4854 +
4855 +int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
4856 +       lb_addr *eloc, Uint32 *elen, Uint32 *offset, struct buffer_head **bh)
4857 +{
4858 +       int etype, lbcount = 0;
4859 +
4860 +       if (block < 0)
4861 +       {
4862 +               printk(KERN_ERR "udf: inode_bmap: block < 0\n");
4863 +               return -1;
4864 +       }
4865 +       if (!inode)
4866 +       {
4867 +               printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
4868 +               return -1;
4869 +       }
4870 +
4871 +       *extoffset = 0;
4872 +       *elen = 0;
4873 +       *bloc = UDF_I_LOCATION(inode);
4874 +
4875 +       do
4876 +       {
4877 +               if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
4878 +               {
4879 +                       *offset = block - lbcount;
4880 +                       return -1;
4881 +               }
4882 +               lbcount += ((*elen + inode->i_sb->s_blocksize - 1) >>
4883 +                       inode->i_sb->s_blocksize_bits);
4884 +       } while (lbcount <= block);
4885 +
4886 +       *offset = block + ((*elen + inode->i_sb->s_blocksize - 1) >>
4887 +               inode->i_sb->s_blocksize_bits) - lbcount;
4888 +
4889 +       return etype;
4890 +}
4891 +
4892 +int udf_bmap(struct inode *inode, int block)
4893 +{
4894 +       lb_addr eloc, bloc;
4895 +       Uint32 offset, extoffset, elen;
4896 +       struct buffer_head *bh = NULL;
4897 +       int ret;
4898 +
4899 +       if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
4900 +               ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
4901 +       else
4902 +               ret = 0;
4903 +
4904 +       if (bh)
4905 +               udf_release_data(bh);
4906 +
4907 +       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
4908 +               return udf_fixed_to_variable(ret);
4909 +       else
4910 +               return ret;
4911 +}
4912 +
4913 +int udf_readpage_adinicb (struct file * file, struct page * page)
4914 +{
4915 +       struct inode * inode;
4916 +       struct buffer_head *bh;
4917 +       int block;
4918 +
4919 +       inode = file->f_dentry->d_inode;
4920 +
4921 +       memset((char *)page_address(page), 0, PAGE_SIZE);
4922 +       block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
4923 +       bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize);
4924 +       if (!buffer_uptodate(bh))
4925 +       {
4926 +               ll_rw_block (READ, 1, &bh);
4927 +               wait_on_buffer(bh);
4928 +       }
4929 +       memcpy((char *)page_address(page), bh->b_data + udf_ext0_offset(inode),
4930 +               inode->i_size);
4931 +       brelse(bh);
4932 +       set_bit(PG_uptodate, &page->flags);
4933 +       return 0;
4934 +}
4935 diff -Nru linux/fs/udf/lowlevel.c linux.new/fs/udf/lowlevel.c
4936 --- linux/fs/udf/lowlevel.c     Thu Jan  1 01:00:00 1970
4937 +++ linux.new/fs/udf/lowlevel.c Fri Sep  7 11:32:16 2001
4938 @@ -0,0 +1,390 @@
4939 +/*
4940 + * lowlevel.c
4941 + *
4942 + * PURPOSE
4943 + *  Low Level Device Routines for the UDF filesystem
4944 + *
4945 + * CONTACTS
4946 + *     E-mail regarding any portion of the Linux UDF file system should be
4947 + *     directed to the development team mailing list (run by majordomo):
4948 + *             linux_udf@hootie.lvld.hp.com
4949 + *
4950 + * COPYRIGHT
4951 + *     This file is distributed under the terms of the GNU General Public
4952 + *     License (GPL). Copies of the GPL can be obtained from:
4953 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
4954 + *     Each contributing author retains all rights to their own work.
4955 + *
4956 + *  (C) 1999-2000 Ben Fennema
4957 + *
4958 + * HISTORY
4959 + *
4960 + *  03/26/99 blf  Created.
4961 + */
4962 +
4963 +#include "udfdecl.h"
4964 +
4965 +#include <linux/blkdev.h>
4966 +#include <linux/cdrom.h>
4967 +#include <asm/uaccess.h>
4968 +#include <scsi/scsi.h>
4969 +
4970 +typedef struct scsi_device Scsi_Device;
4971 +typedef struct scsi_cmnd   Scsi_Cmnd;
4972 +
4973 +#include <scsi/scsi_ioctl.h>
4974 +
4975 +#include <linux/udf_fs.h>
4976 +#include "udf_sb.h"
4977 +
4978 +unsigned int 
4979 +udf_get_last_session(struct super_block *sb)
4980 +{
4981 +       struct cdrom_multisession ms_info;
4982 +       unsigned int vol_desc_start;
4983 +       kdev_t dev = sb->s_dev;
4984 +       struct inode inode_fake;
4985 +       extern struct file_operations * get_blkfops(unsigned int);
4986 +       int i;
4987 +
4988 +       vol_desc_start=0;
4989 +       if (get_blkfops(MAJOR(dev))->ioctl!=NULL)
4990 +       {
4991 +               /* Whoops.  We must save the old FS, since otherwise
4992 +                * we would destroy the kernels idea about FS on root
4993 +                * mount in read_super... [chexum]
4994 +                */
4995 +               mm_segment_t old_fs=get_fs();
4996 +               inode_fake.i_rdev=dev;
4997 +               ms_info.addr_format=CDROM_LBA;
4998 +               set_fs(KERNEL_DS);
4999 +               i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
5000 +                                               NULL,
5001 +                                               CDROMMULTISESSION,
5002 +                                               (unsigned long) &ms_info);
5003 +               set_fs(old_fs);
5004 +
5005 +#define WE_OBEY_THE_WRITTEN_STANDARDS 1
5006 +
5007 +               if (i == 0)
5008 +               {
5009 +                       udf_debug("XA disk: %s, vol_desc_start=%d\n",
5010 +                               (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
5011 +#if WE_OBEY_THE_WRITTEN_STANDARDS
5012 +                       if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
5013 +#endif
5014 +                               vol_desc_start = ms_info.addr.lba;
5015 +               }
5016 +               else
5017 +               {
5018 +                       udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
5019 +               }
5020 +       }
5021 +       else
5022 +       {
5023 +               udf_debug("Device doesn't know how to ioctl?\n");
5024 +       }
5025 +       return vol_desc_start;
5026 +}
5027 +
5028 +#ifdef CDROM_LAST_WRITTEN
5029 +
5030 +static unsigned int
5031 +udf_get_last_written(kdev_t dev, struct inode *inode_fake)
5032 +{
5033 +       extern struct file_operations * get_blkfops(unsigned int);
5034 +       unsigned long lastsector;
5035 +
5036 +       if (!(get_blkfops(MAJOR(dev))->ioctl(inode_fake,
5037 +               NULL,
5038 +               CDROM_LAST_WRITTEN,
5039 +               (unsigned long) &lastsector)))
5040 +       {
5041 +               return lastsector - 1;
5042 +       }
5043 +       else
5044 +               return 0;
5045 +}
5046 +
5047 +#else
5048 +
5049 +static int
5050 +do_scsi(kdev_t dev, struct inode *inode_fake, Uint8 *command, int cmd_len,
5051 +       Uint8 *buffer, Uint32 in_len, Uint32 out_len)
5052 +{
5053 +       extern struct file_operations * get_blkfops(unsigned int);
5054 +       Uint32 *ip;
5055 +
5056 +       ip = (Uint32 *)buffer;
5057 +       ip[0] = in_len;
5058 +       ip[1] = out_len;
5059 +       memcpy(buffer + 8, command, cmd_len);
5060 +       return get_blkfops(MAJOR(dev))->ioctl(inode_fake,
5061 +               NULL, SCSI_IOCTL_SEND_COMMAND, (unsigned long)buffer);
5062 +}
5063 +
5064 +static unsigned int
5065 +udf_get_last_rti(kdev_t dev, struct inode *inode_fake)
5066 +{
5067 +       char buffer[128];
5068 +       int result = 0;
5069 +       int *ip;
5070 +       int track_no;
5071 +       Uint32 trackstart, tracklength, freeblocks;
5072 +       Uint8 cdb[10];
5073 +       unsigned long lastsector = 0;
5074 +       int len;
5075 +
5076 +       ip = (int *)(buffer + 8);
5077 +       memset(cdb, 0, 10);
5078 +       cdb[0] = 0x51;
5079 +       cdb[8] = 32;
5080 +       result = do_scsi(dev, inode_fake, cdb, 10, buffer, 0, 32);
5081 +       if (!result)
5082 +       {
5083 +               track_no = buffer[14];
5084 +               udf_debug("Generic Read Disc Info worked; last track is %d. status=0x%x\n",
5085 +                       track_no, buffer[10] & 0x3);
5086 +               memset(buffer, 0, 128);
5087 +               cdb[0] = 0x52;
5088 +               cdb[1] = 1;
5089 +               cdb[4] = (track_no & 0xFF00) >> 8;
5090 +               cdb[5] = track_no & 0xFF;
5091 +               cdb[8] = 8;
5092 +               result = do_scsi(dev, inode_fake, cdb, 10, buffer, 0, 8);
5093 +               if (!result)
5094 +               {
5095 +                       len = cdb[8] = ((buffer[8] << 8) | (buffer[9] & 0xFF)) + 2;
5096 +                       result = do_scsi(dev, inode_fake, cdb, 10, buffer, 0, len);
5097 +                       if (!result)
5098 +                       {
5099 +                               if (buffer[14] & 0x40)
5100 +                               {
5101 +                                       cdb[4] = ((track_no - 1) & 0xFF00) >> 8;
5102 +                                       cdb[5] = (track_no - 1) & 0xFF;
5103 +                                       result = do_scsi(dev, inode_fake, cdb, 10, buffer, 0, len);
5104 +                               }
5105 +                               if (!result)
5106 +                               {
5107 +                                       trackstart = be32_to_cpu(ip[2]);
5108 +                                       tracklength = be32_to_cpu(ip[6]);
5109 +                                       freeblocks = be32_to_cpu(ip[4]);
5110 +                                       udf_debug("Start %d, length %d, freeblocks %d.\n", trackstart, tracklength, freeblocks);
5111 +                                       if (buffer[14] & 0x20)
5112 +                                       {
5113 +                                               if (buffer[14] & 0x10)
5114 +                                               {
5115 +                                                       udf_debug("Packet size is %d.\n", be32_to_cpu(ip[5]));
5116 +                                                       lastsector = trackstart + tracklength - 1;
5117 +                                               }
5118 +                                               else
5119 +                                               {
5120 +                                                       udf_debug("Variable packet written track.\n");
5121 +                                                       lastsector = trackstart + tracklength - 1;
5122 +                                                       if (freeblocks)
5123 +                                                       {
5124 +                                                               lastsector = lastsector - freeblocks - 7;
5125 +                                                       }
5126 +                                               }
5127 +                                       }
5128 +                               }
5129 +                       }
5130 +               }
5131 +       }
5132 +       return lastsector;
5133 +}
5134 +
5135 +static unsigned int
5136 +udf_get_toc_entry(kdev_t dev, struct inode *inode_fake)
5137 +{
5138 +       extern struct file_operations * get_blkfops(unsigned int);
5139 +       struct cdrom_tocentry toc;
5140 +       int res, lastsector = 0;
5141 +
5142 +       toc.cdte_format = CDROM_LBA;
5143 +       toc.cdte_track = 0xAA;
5144 +       
5145 +       if (!(res = get_blkfops(MAJOR(dev))->ioctl(inode_fake,
5146 +                       NULL,
5147 +                       CDROMREADTOCENTRY,
5148 +                       (unsigned long) &toc)))
5149 +       {
5150 +               lastsector = toc.cdte_addr.lba - 1;
5151 +       }
5152 +
5153 +       return lastsector;
5154 +}
5155 +
5156 +static unsigned int
5157 +udf_get_capacity(kdev_t dev, struct inode *inode_fake)
5158 +{
5159 +       char buffer[128];
5160 +       int result = 0;
5161 +       int *ip;
5162 +       Uint8 cdb[10];
5163 +       unsigned long lastsector = 0;
5164 +
5165 +       ip = (int *)(buffer + 8);
5166 +       memset(cdb, 0, 10);
5167 +
5168 +       cdb[0] = READ_CAPACITY;
5169 +       result = do_scsi(dev, inode_fake, cdb, 10, buffer, 0, 8);
5170 +       if (!result)
5171 +               lastsector = be32_to_cpu(ip[0]);
5172 +
5173 +       return lastsector;
5174 +}
5175 +
5176 +static int
5177 +is_mmc(kdev_t dev, struct inode *inode_fake)
5178 +{
5179 +       Uint8 buffer[142];
5180 +       int result = 0, n;
5181 +       Uint8 cdb[6];
5182 +       Uint8 *data = &buffer[8];
5183 +       int len = 4;
5184 +
5185 +       cdb[0] = MODE_SENSE;
5186 +       cdb[2] = 0x2A;
5187 +       cdb[4] = len;
5188 +       cdb[1] = cdb[3] = cdb[5] = 0;
5189 +
5190 +       memset(buffer, 0, 142);
5191 +       result = do_scsi(dev, inode_fake, cdb, 6, buffer, 0, len);
5192 +       if (!result)
5193 +       {
5194 +               len = cdb[4] = data[3] + 4 + 2;
5195 +               result = do_scsi(dev, inode_fake, cdb, 6, buffer, 0, len);
5196 +               if (!result)
5197 +               {
5198 +                       n = data[3] + 4;
5199 +                       len = cdb[4] = n + 2 + data[n+1];
5200 +                       result = do_scsi(dev, inode_fake, cdb, 6, buffer, 0, len);
5201 +                       if (!result && ((data[n] & 0x3F) == 0x2A))
5202 +                       {
5203 +                               udf_debug("Page Code=0x%02x  PS=0x%1x  Page Length=0x%02x\n",
5204 +                                       data[n] & 0x3F, (data[n] >> 7) & 0x01, data[n+1]);
5205 +                               udf_debug("DVD-RAM R/W(%c/%c)  DVD-R R/W(%c/%c)  DVD-ROM R(%c)\n",
5206 +                                       data[n+2] & 0x20 ? 'Y' : 'N', data[n+3] & 0x20 ? 'Y' : 'N',
5207 +                                       data[n+2] & 0x10 ? 'Y' : 'N', data[n+3] & 0x10 ? 'Y' : 'N',
5208 +                                       data[n+2] & 0x08 ? 'Y' : 'N');
5209 +                               udf_debug("CD-RW   R/W(%c/%c)  CD-R  R/W(%c/%c)  Fixed Packet (%c)\n",
5210 +                                       data[n+2] & 0x02 ? 'Y' : 'N', data[n+3] & 0x02 ? 'Y' : 'N',
5211 +                                       data[n+2] & 0x01 ? 'Y' : 'N', data[n+3] & 0x01 ? 'Y' : 'N',
5212 +                                       data[n+2] & 0x04 ? 'Y' : 'N');
5213 +                               udf_debug("Multi Session (%c)  Mode 2 Form 2/1 (%c/%c) Digital Port (2)/(1) (%c/%c)\n",
5214 +                                       data[n+4] & 0x40 ? 'Y' : 'N', data[n+4] & 0x20 ? 'Y' : 'N',
5215 +                                       data[n+4] & 0x10 ? 'Y' : 'N', data[n+4] & 0x08 ? 'Y' : 'N',
5216 +                                       data[n+4] & 0x04 ? 'Y' : 'N');
5217 +                               udf_debug("Composite (%c)  Audio Play (%c)  Read Bar Code (%c)  UPC (%c)  ISRC (%c)\n",
5218 +                                       data[n+4] & 0x02 ? 'Y' : 'N', data[n+4] & 0x01 ? 'Y' : 'N',
5219 +                                       data[n+5] & 0x80 ? 'Y' : 'N', data[n+5] & 0x40 ? 'Y' : 'N',
5220 +                                       data[n+5] & 0x20 ? 'Y' : 'N');
5221 +                               udf_debug("C2 Pointers are supported (%c)  R-W De-interleved & corrected (%c)\n",
5222 +                                       data[n+5] & 0x10 ? 'Y' : 'N', data[n+5] & 0x80 ? 'Y' : 'N');
5223 +                               udf_debug("R-W Supported (%c)  CD-DA Stream is Accurate (%c)  CD-DA Commands Supported (%c)\n",
5224 +                                       data[n+5] & 0x04 ? 'Y' : 'N', data[n+5] & 0x02 ? 'Y' : 'N',
5225 +                                       data[n+5] & 0x01 ? 'Y' : 'N');
5226 +                               udf_debug("Loading Mechanism Type=0x%03x  Eject (%c)  Prevent Jumper (%c)\n",
5227 +                                       (data[n+6] >> 5) & 0x07, data[n+6] & 0x08 ? 'Y' : 'N',
5228 +                                       data[n+6] & 0x04 ? 'Y' : 'N');
5229 +                               udf_debug("Lock State (%c)  Lock(%c)\n",
5230 +                                       data[n+6] & 0x02 ? 'Y' : 'N', data[n+6] & 0x01 ? 'Y' : 'N');
5231 +                               udf_debug("P through W in Lead-In (%c)  Side Change Capable (%c)  S/W Slot Selection (%c)\n",
5232 +                                       data[n+7] & 0x20 ? 'Y' : 'N', data[n+7] & 0x10 ? 'Y' : 'N',
5233 +                                       data[n+7] & 0x08 ? 'Y' : 'N');
5234 +                               udf_debug("Changer Supports Disc Present (%c)  Seperate Channel Mute (%c)  Seperate Volume Levels (%c)\n",
5235 +                                       data[n+7] & 0x04 ? 'Y' : 'N', data[n+7] & 0x02 ? 'Y' : 'N',
5236 +                                       data[n+7] & 0x01 ? 'Y' : 'N');
5237 +                               udf_debug("Maximum Read Speed Supported (in kBps)=0x%04x (Obsolete)\n",
5238 +                                       (data[n+8] << 8) | (data[n+9] & 0xFF));
5239 +                               udf_debug("Number of Volume Levels Support=0x%04x\n",
5240 +                                       (data[n+10] << 8) | (data[n+11] & 0xFF));
5241 +                               udf_debug("Buffer Size supported by Drive (in KBytes)=0x%04x\n",
5242 +                                       (data[n+12] << 8) | (data[n+13] & 0xFF));
5243 +                               udf_debug("Current Read Speed Selected (in kBps)=0x%04x (Obsolete)\n",
5244 +                                       (data[n+14] << 8) | (data[n+15] & 0xFF));
5245 +                               udf_debug("Digital Out: Length=0x%01x  LSBF (%c)  RCK (%c)  BCKF (%c)\n",
5246 +                                       (data[n+17] >> 4) & 0x03, data[n+17] & 0x08 ? 'Y' : 'N',
5247 +                                       data[n+17] & 0x04 ? 'Y' : 'N', data[n+17] & 0x02 ? 'Y' : 'N');
5248 +                               udf_debug("Maximum Write Speed Supported (in kBps)=0x%04x (Obsolete)\n",
5249 +                                       (data[n+18] << 8) | (data[n+19] & 0xFF));
5250 +                               udf_debug("Current Write Speed Selected (in kBps)=0x%04x (Obsolete)\n",
5251 +                                       (data[n+20] << 8) | (data[n+21] & 0xFF));
5252 +                               udf_debug("Copy Management Revision Supported=%04x\n",
5253 +                                       (data[n+22] << 8) | (data[n+23] & 0xFF));
5254 +                       }
5255 +                       else 
5256 +                               return 0;
5257 +               }
5258 +       }
5259 +       return !result;
5260 +}
5261 +
5262 +#endif
5263 +
5264 +unsigned int
5265 +udf_get_last_block(struct super_block *sb)
5266 +{
5267 +       kdev_t dev = sb->s_dev;
5268 +       struct inode inode_fake;
5269 +       extern struct file_operations * get_blkfops(unsigned int);
5270 +       int ret;
5271 +       unsigned long lblock;
5272 +       int accurate = 0;
5273 +
5274 +       if (get_blkfops(MAJOR(dev))->ioctl!=NULL)
5275 +       {
5276 +      /* Whoops.  We must save the old FS, since otherwise
5277 +       * we would destroy the kernels idea about FS on root
5278 +       * mount in read_super... [chexum]
5279 +       */
5280 +               mm_segment_t old_fs=get_fs();
5281 +               inode_fake.i_rdev=dev;
5282 +               set_fs(KERNEL_DS);
5283 +
5284 +               lblock = 0;
5285 +               ret = get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
5286 +                               NULL,
5287 +                               BLKGETSIZE,
5288 +                               (unsigned long) &lblock);
5289 +
5290 +               if (!ret && lblock != 0x7FFFFFFF) /* Hard Disk */
5291 +               {
5292 +                       udf_debug("BLKGETSIZE lblock=%ld\n", lblock);
5293 +                       lblock = ((512 * lblock) / sb->s_blocksize) - 1;
5294 +                       accurate = 1;
5295 +               }
5296 +               else /* CDROM */
5297 +               {
5298 +#ifdef CDROM_LAST_WRITTEN
5299 +                       if ((lblock = udf_get_last_written(dev, &inode_fake)))
5300 +                       {
5301 +                               udf_debug("last_written lblock=%ld\n", lblock);
5302 +                               accurate = 1;
5303 +                       }
5304 +#else
5305 +                       if (is_mmc(dev, &inode_fake) &&
5306 +                               (lblock = udf_get_last_rti(dev, &inode_fake)))
5307 +                       {
5308 +                               udf_debug("LAST_RTI lblock=%ld\n", lblock);
5309 +                       }
5310 +                       else if ((lblock = udf_get_toc_entry(dev, &inode_fake)))
5311 +                       {
5312 +                               udf_debug("TOC_ENTRY lblock=%ld\n", lblock);
5313 +                       }
5314 +                       else if ((lblock = udf_get_capacity(dev, &inode_fake)))
5315 +                       {
5316 +                               udf_debug("READ_CAPACITY lblock=%ld\n", lblock);
5317 +                       }
5318 +#endif
5319 +               }
5320 +               set_fs(old_fs);
5321 +               return lblock;
5322 +       }
5323 +       else
5324 +       {
5325 +               udf_debug("Device doesn't know how to ioctl?\n");
5326 +       }
5327 +       return 0;
5328 +}
5329 diff -Nru linux/fs/udf/misc.c linux.new/fs/udf/misc.c
5330 --- linux/fs/udf/misc.c Thu Jan  1 01:00:00 1970
5331 +++ linux.new/fs/udf/misc.c     Fri Sep  7 11:32:16 2001
5332 @@ -0,0 +1,515 @@
5333 +/*
5334 + * misc.c
5335 + *
5336 + * PURPOSE
5337 + *     Miscellaneous routines for the OSTA-UDF(tm) filesystem.
5338 + *
5339 + * CONTACTS
5340 + *     E-mail regarding any portion of the Linux UDF file system should be
5341 + *     directed to the development team mailing list (run by majordomo):
5342 + *             linux_udf@hootie.lvld.hp.com
5343 + *
5344 + * COPYRIGHT
5345 + *     This file is distributed under the terms of the GNU General Public
5346 + *     License (GPL). Copies of the GPL can be obtained from:
5347 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
5348 + *     Each contributing author retains all rights to their own work.
5349 + *
5350 + *  (C) 1998 Dave Boynton
5351 + *  (C) 1998-2000 Ben Fennema
5352 + *  (C) 1999-2000 Stelias Computing Inc
5353 + *
5354 + * HISTORY
5355 + *
5356 + *  04/19/99 blf  partial support for reading/writing specific EA's
5357 + */
5358 +
5359 +#include "udfdecl.h"
5360 +
5361 +#if defined(__linux__) && defined(__KERNEL__)
5362 +
5363 +#include "udf_sb.h"
5364 +#include "udf_i.h"
5365 +
5366 +#include <linux/fs.h>
5367 +#include <linux/string.h>
5368 +#include <linux/udf_fs.h>
5369 +
5370 +#else
5371 +
5372 +#include <sys/types.h>
5373 +#include <stdio.h>
5374 +#include <unistd.h>
5375 +#include <string.h>
5376 +
5377 +int udf_blocksize=0;
5378 +int udf_errno=0;
5379 +
5380 +void 
5381 +udf_setblocksize(int size)
5382 +{
5383 +       udf_blocksize=size;
5384 +}
5385 +#endif
5386 +
5387 +Uint32
5388 +udf64_low32(Uint64 indat)
5389 +{
5390 +       return indat & 0x00000000FFFFFFFFULL;
5391 +}
5392 +
5393 +Uint32
5394 +udf64_high32(Uint64 indat)
5395 +{
5396 +       return indat >> 32;
5397 +}
5398 +
5399 +uid_t udf_convert_uid(int uidin)
5400 +{
5401 +       if ( uidin == -1 )
5402 +               return 0;
5403 +       if ( uidin > (64*1024U - 1) ) /* 16 bit UID */
5404 +               return 0;
5405 +       return uidin;
5406 +}
5407 +
5408 +gid_t udf_convert_gid(int gidin)
5409 +{
5410 +       if ( gidin == -1 )
5411 +               return 0;
5412 +       if ( gidin > (64*1024U - 1) ) /* 16 bit GID */
5413 +               return 0;
5414 +       return gidin;
5415 +}
5416 +
5417 +#if defined(__linux__) && defined(__KERNEL__)
5418 +
5419 +extern struct buffer_head *
5420 +udf_tread(struct super_block *sb, int block, int size)
5421 +{
5422 +       if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
5423 +               return bread(sb->s_dev, udf_fixed_to_variable(block), size);
5424 +       else
5425 +               return bread(sb->s_dev, block, size);
5426 +}
5427 +
5428 +extern struct GenericAttrFormat *
5429 +udf_add_extendedattr(struct inode * inode, Uint32 size, Uint32 type,
5430 +       Uint8 loc, struct buffer_head **bh)
5431 +{
5432 +       Uint8 *ea = NULL, *ad = NULL;
5433 +       long_ad eaicb;
5434 +       int offset;
5435 +
5436 +       *bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
5437 +
5438 +       if (UDF_I_EXTENDED_FE(inode) == 0)
5439 +       {
5440 +               struct FileEntry *fe;
5441 +
5442 +               fe = (struct FileEntry *)(*bh)->b_data;
5443 +               eaicb = lela_to_cpu(fe->extendedAttrICB);
5444 +               offset = sizeof(struct FileEntry);
5445 +       }
5446 +       else
5447 +       {
5448 +               struct ExtendedFileEntry *efe;
5449 +
5450 +               efe = (struct ExtendedFileEntry *)(*bh)->b_data;
5451 +               eaicb = lela_to_cpu(efe->extendedAttrICB);
5452 +               offset = sizeof(struct ExtendedFileEntry);
5453 +       }
5454 +
5455 +       ea = &(*bh)->b_data[offset];
5456 +       if (UDF_I_LENEATTR(inode))
5457 +               offset += UDF_I_LENEATTR(inode);
5458 +       else
5459 +               size += sizeof(struct ExtendedAttrHeaderDesc);
5460 +
5461 +       ad = &(*bh)->b_data[offset];
5462 +       if (UDF_I_LENALLOC(inode))
5463 +               offset += UDF_I_LENALLOC(inode);
5464 +
5465 +       offset = inode->i_sb->s_blocksize - offset;
5466 +
5467 +       /* TODO - Check for FreeEASpace */
5468 +
5469 +       if (loc & 0x01 && offset >= size)
5470 +       {
5471 +               struct ExtendedAttrHeaderDesc *eahd;
5472 +               eahd = (struct ExtendedAttrHeaderDesc *)ea;
5473 +
5474 +               if (UDF_I_LENALLOC(inode))
5475 +               {
5476 +                       memmove(&ad[size], ad, UDF_I_LENALLOC(inode));
5477 +               }
5478 +
5479 +               if (UDF_I_LENEATTR(inode))
5480 +               {
5481 +                       /* check checksum/crc */
5482 +                       if (le16_to_cpu(eahd->descTag.tagIdent) != TID_EXTENDED_ATTRE_HEADER_DESC ||
5483 +                               le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
5484 +                       {
5485 +                               udf_release_data(*bh);
5486 +                               return NULL;
5487 +                       }
5488 +               }
5489 +               else
5490 +               {
5491 +                       size -= sizeof(struct ExtendedAttrHeaderDesc);
5492 +                       UDF_I_LENEATTR(inode) += sizeof(struct ExtendedAttrHeaderDesc);
5493 +                       eahd->descTag.tagIdent = cpu_to_le16(TID_EXTENDED_ATTRE_HEADER_DESC);
5494 +                       eahd->descTag.descVersion = cpu_to_le16(2);
5495 +                       eahd->descTag.tagSerialNum = cpu_to_le16(1);
5496 +                       eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
5497 +                       eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
5498 +                       eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
5499 +               }
5500 +
5501 +               offset = UDF_I_LENEATTR(inode);
5502 +               if (type < 2048)
5503 +               {
5504 +                       if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
5505 +                       {
5506 +                               Uint32 aal = le32_to_cpu(eahd->appAttrLocation);
5507 +                               memmove(&ea[offset - aal + size],
5508 +                                       &ea[aal], offset - aal);
5509 +                               offset -= aal;
5510 +                               eahd->appAttrLocation = cpu_to_le32(aal + size);
5511 +                       }
5512 +                       if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode))
5513 +                       {
5514 +                               Uint32 ial = le32_to_cpu(eahd->impAttrLocation);
5515 +                               memmove(&ea[offset - ial + size],
5516 +                                       &ea[ial], offset - ial);
5517 +                               offset -= ial;
5518 +                               eahd->impAttrLocation = cpu_to_le32(ial + size);
5519 +                       }
5520 +               }
5521 +               else if (type < 65536)
5522 +               {
5523 +                       if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode))
5524 +                       {
5525 +                               Uint32 aal = le32_to_cpu(eahd->appAttrLocation);
5526 +                               memmove(&ea[offset - aal + size],
5527 +                                       &ea[aal], offset - aal);
5528 +                               offset -= aal;
5529 +                               eahd->appAttrLocation = cpu_to_le32(aal + size);
5530 +                       }
5531 +               }
5532 +               /* rewrite CRC + checksum of eahd */
5533 +               UDF_I_LENEATTR(inode) += size;
5534 +               return (struct GenericAttrFormat *)&ea[offset];
5535 +       }
5536 +       if (loc & 0x02)
5537 +       {
5538 +       }
5539 +       udf_release_data(*bh);
5540 +       return NULL;
5541 +}
5542 +
5543 +extern struct GenericAttrFormat *
5544 +udf_get_extendedattr(struct inode * inode, Uint32 type, Uint8 subtype,
5545 +       struct buffer_head **bh)
5546 +{
5547 +       struct GenericAttrFormat *gaf;
5548 +       Uint8 *ea = NULL;
5549 +       long_ad eaicb;
5550 +       Uint32 offset;
5551 +
5552 +       *bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
5553 +
5554 +       if (UDF_I_EXTENDED_FE(inode) == 0)
5555 +       {
5556 +               struct FileEntry *fe;
5557 +
5558 +               fe = (struct FileEntry *)(*bh)->b_data;
5559 +               eaicb = lela_to_cpu(fe->extendedAttrICB);
5560 +               if (UDF_I_LENEATTR(inode))
5561 +                       ea = fe->extendedAttr;
5562 +       }
5563 +       else
5564 +       {
5565 +               struct ExtendedFileEntry *efe;
5566 +
5567 +               efe = (struct ExtendedFileEntry *)(*bh)->b_data;
5568 +               eaicb = lela_to_cpu(efe->extendedAttrICB);
5569 +               if (UDF_I_LENEATTR(inode))
5570 +                       ea = efe->extendedAttr;
5571 +       }
5572 +
5573 +       if (UDF_I_LENEATTR(inode))
5574 +       {
5575 +               struct ExtendedAttrHeaderDesc *eahd;
5576 +               eahd = (struct ExtendedAttrHeaderDesc *)ea;
5577 +
5578 +               /* check checksum/crc */
5579 +               if (le16_to_cpu(eahd->descTag.tagIdent) != TID_EXTENDED_ATTRE_HEADER_DESC ||
5580 +                       le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum)
5581 +               {
5582 +                       udf_release_data(*bh);
5583 +                       return NULL;
5584 +               }
5585 +       
5586 +               if (type < 2048)
5587 +                       offset = sizeof(struct ExtendedAttrHeaderDesc);
5588 +               else if (type < 65536)
5589 +                       offset = le32_to_cpu(eahd->impAttrLocation);
5590 +               else
5591 +                       offset = le32_to_cpu(eahd->appAttrLocation);
5592 +
5593 +               while (offset < UDF_I_LENEATTR(inode))
5594 +               {
5595 +                       gaf = (struct GenericAttrFormat *)&ea[offset];
5596 +                       if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype)
5597 +                               return gaf;
5598 +                       else
5599 +                               offset += le32_to_cpu(gaf->attrLength);
5600 +               }
5601 +       }
5602 +
5603 +       udf_release_data(*bh);
5604 +       if (eaicb.extLength)
5605 +       {
5606 +               /* TODO */
5607 +       }
5608 +       return NULL;
5609 +}
5610 +
5611 +extern struct buffer_head *
5612 +udf_read_untagged(struct super_block *sb, Uint32 block, Uint32 offset)
5613 +{
5614 +       struct buffer_head *bh = NULL;
5615 +
5616 +       /* Read the block */
5617 +       bh = udf_tread(sb, block+offset, sb->s_blocksize);
5618 +       if (!bh)
5619 +       {
5620 +               printk(KERN_ERR "udf: udf_read_untagged(%p,%d,%d) failed\n",
5621 +                       sb, block, offset);
5622 +               return NULL;
5623 +       }
5624 +       return bh;
5625 +}
5626 +
5627 +/*
5628 + * udf_read_tagged
5629 + *
5630 + * PURPOSE
5631 + *     Read the first block of a tagged descriptor.
5632 + *
5633 + * HISTORY
5634 + *     July 1, 1997 - Andrew E. Mileski
5635 + *     Written, tested, and released.
5636 + */
5637 +extern struct buffer_head *
5638 +udf_read_tagged(struct super_block *sb, Uint32 block, Uint32 location, Uint16 *ident)
5639 +{
5640 +       tag *tag_p;
5641 +       struct buffer_head *bh = NULL;
5642 +       register Uint8 checksum;
5643 +       register int i;
5644 +
5645 +       /* Read the block */
5646 +       if (block == 0xFFFFFFFF)
5647 +               return NULL;
5648 +
5649 +       bh = udf_tread(sb, block, sb->s_blocksize);
5650 +       if (!bh)
5651 +       {
5652 +               udf_debug("block=%d, location=%d: read failed\n", block, location);
5653 +               return NULL;
5654 +       }
5655 +
5656 +       tag_p = (tag *)(bh->b_data);
5657 +
5658 +       *ident = le16_to_cpu(tag_p->tagIdent);
5659 +
5660 +       if ( location != le32_to_cpu(tag_p->tagLocation) )
5661 +       {
5662 +               udf_debug("location mismatch block %d, tag %d != %d\n",
5663 +                       block, le32_to_cpu(tag_p->tagLocation), location);
5664 +               goto error_out;
5665 +       }
5666 +       
5667 +       /* Verify the tag checksum */
5668 +       checksum = 0U;
5669 +       for (i = 0; i < 4; i++)
5670 +               checksum += (Uint8)(bh->b_data[i]);
5671 +       for (i = 5; i < 16; i++)
5672 +               checksum += (Uint8)(bh->b_data[i]);
5673 +       if (checksum != tag_p->tagChecksum) {
5674 +               printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
5675 +               goto error_out;
5676 +       }
5677 +
5678 +       /* Verify the tag version */
5679 +       if (le16_to_cpu(tag_p->descVersion) != 0x0002U &&
5680 +               le16_to_cpu(tag_p->descVersion) != 0x0003U)
5681 +       {
5682 +               udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n",
5683 +                       le16_to_cpu(tag_p->descVersion), block);
5684 +               goto error_out;
5685 +       }
5686 +
5687 +       /* Verify the descriptor CRC */
5688 +       if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
5689 +               le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag),
5690 +                       le16_to_cpu(tag_p->descCRCLength), 0))
5691 +       {
5692 +               return bh;
5693 +       }
5694 +       udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
5695 +               block, le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength));
5696 +
5697 +error_out:
5698 +       brelse(bh);
5699 +       return NULL;
5700 +}
5701 +
5702 +extern struct buffer_head *
5703 +udf_read_ptagged(struct super_block *sb, lb_addr loc, Uint32 offset, Uint16 *ident)
5704 +{
5705 +       return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
5706 +               loc.logicalBlockNum + offset, ident);
5707 +}
5708 +
5709 +void udf_release_data(struct buffer_head *bh)
5710 +{
5711 +       if (bh)
5712 +               brelse(bh);
5713 +}
5714 +
5715 +#endif
5716 +
5717 +void udf_update_tag(char *data, int length)
5718 +{
5719 +       tag *tptr = (tag *)data;
5720 +       int i;
5721 +
5722 +       length -= sizeof(tag);
5723 +
5724 +       tptr->tagChecksum = 0;
5725 +       tptr->descCRCLength = le16_to_cpu(length);
5726 +       tptr->descCRC = le16_to_cpu(udf_crc(data + sizeof(tag), length, 0));
5727 +
5728 +       for (i=0; i<16; i++)
5729 +               if (i != 4)
5730 +                       tptr->tagChecksum += (Uint8)(data[i]);
5731 +}
5732 +
5733 +void udf_new_tag(char *data, Uint16 ident, Uint16 version, Uint16 snum,
5734 +       Uint32 loc, int length)
5735 +{
5736 +       tag *tptr = (tag *)data;
5737 +       tptr->tagIdent = le16_to_cpu(ident);
5738 +       tptr->descVersion = le16_to_cpu(version);
5739 +       tptr->tagSerialNum = le16_to_cpu(snum);
5740 +       tptr->tagLocation = le32_to_cpu(loc);
5741 +       udf_update_tag(data, length);
5742 +}
5743 +
5744 +#ifndef __KERNEL__
5745 +/*
5746 + * udf_read_tagged_data
5747 + *
5748 + * PURPOSE
5749 + *     Read the first block of a tagged descriptor.
5750 + *     Usable from user-land.
5751 + *
5752 + * HISTORY
5753 + *       10/4/98 dgb: written
5754 + */
5755 +int
5756 +udf_read_tagged_data(char *buffer, int size, int fd, int block, int offset)
5757 +{
5758 +       tag *tag_p;
5759 +       register Uint8 checksum;
5760 +       register int i;
5761 +       unsigned long offs;
5762 +
5763 +       if (!buffer)
5764 +       {
5765 +               udf_errno = 1;
5766 +               return -1;
5767 +       }
5768 +
5769 +       if ( !udf_blocksize )
5770 +       {
5771 +               udf_errno = 2;
5772 +               return -1;
5773 +       }
5774 +
5775 +       if ( size < udf_blocksize )
5776 +       {
5777 +               udf_errno=3;
5778 +               return -1;
5779 +       }
5780 +       udf_errno=0;
5781 +       
5782 +       offs=(long)block * udf_blocksize;
5783 +       if ( lseek(fd, offs, SEEK_SET) != offs ) {
5784 +               udf_errno=4;
5785 +               return -1;
5786 +       }
5787 +
5788 +       i=read(fd, buffer, udf_blocksize);
5789 +       if ( i < udf_blocksize ) {
5790 +               udf_errno=5;
5791 +               return -1;
5792 +       }
5793 +
5794 +       tag_p = (tag *)(buffer);
5795 +
5796 +       /* Verify the tag location */
5797 +       if ((block-offset) != tag_p->tagLocation) {
5798 +#ifdef __KERNEL__
5799 +               printk(KERN_ERR "udf: location mismatch block %d, tag %d\n",
5800 +                       block, tag_p->tagLocation);
5801 +#else
5802 +               udf_errno=6;
5803 +#endif
5804 +               goto error_out;
5805 +       }
5806 +       
5807 +       /* Verify the tag checksum */
5808 +       checksum = 0U;
5809 +       for (i = 0; i < 4; i++)
5810 +               checksum += (Uint8)(buffer[i]);
5811 +       for (i = 5; i < 16; i++)
5812 +               checksum += (Uint8)(buffer[i]);
5813 +       if (checksum != tag_p->tagChecksum) {
5814 +#ifdef __KERNEL__
5815 +               printk(KERN_ERR "udf: tag checksum failed\n");
5816 +#else
5817 +               udf_errno=7;
5818 +#endif
5819 +               goto error_out;
5820 +       }
5821 +
5822 +       /* Verify the tag version */
5823 +       if (tag_p->descVersion != 0x0002U) {
5824 +#ifdef __KERNEL__
5825 +               printk(KERN_ERR "udf: tag version 0x%04x != 0x0002U\n",
5826 +                       tag_p->descVersion);
5827 +#else
5828 +               udf_errno=8;
5829 +#endif
5830 +               goto error_out;
5831 +       }
5832 +
5833 +       /* Verify the descriptor CRC */
5834 +       if (tag_p->descCRC == udf_crc(buffer + 16, tag_p->descCRCLength, 0)) {
5835 +               udf_errno=0;
5836 +               return 0;
5837 +       }
5838 +#ifdef __KERNEL__
5839 +       printk(KERN_ERR "udf: crc failure in udf_read_tagged\n");
5840 +#else
5841 +       udf_errno=9;
5842 +#endif
5843 +
5844 +error_out:
5845 +       return -1;
5846 +}
5847 +#endif
5848 diff -Nru linux/fs/udf/namei.c linux.new/fs/udf/namei.c
5849 --- linux/fs/udf/namei.c        Thu Jan  1 01:00:00 1970
5850 +++ linux.new/fs/udf/namei.c    Fri Sep  7 11:32:16 2001
5851 @@ -0,0 +1,1609 @@
5852 +/*
5853 + * namei.c
5854 + *
5855 + * PURPOSE
5856 + *      Inode name handling routines for the OSTA-UDF(tm) filesystem.
5857 + *
5858 + * CONTACTS
5859 + *      E-mail regarding any portion of the Linux UDF file system should be
5860 + *      directed to the development team mailing list (run by majordomo):
5861 + *              linux_udf@hootie.lvld.hp.com
5862 + *
5863 + * COPYRIGHT
5864 + *      This file is distributed under the terms of the GNU General Public
5865 + *      License (GPL). Copies of the GPL can be obtained from:
5866 + *              ftp://prep.ai.mit.edu/pub/gnu/GPL
5867 + *      Each contributing author retains all rights to their own work.
5868 + *
5869 + *  (C) 1998-2000 Ben Fennema
5870 + *  (C) 1999-2000 Stelias Computing Inc
5871 + *
5872 + * HISTORY
5873 + *
5874 + *  12/12/98 blf  Created. Split out the lookup code from dir.c
5875 + *  04/19/99 blf  link, mknod, symlink support
5876 + */
5877 +
5878 +#include "udfdecl.h"
5879 +
5880 +#if defined(__linux__) && defined(__KERNEL__)
5881 +#include <linux/version.h>
5882 +#include "udf_i.h"
5883 +#include "udf_sb.h"
5884 +#include <linux/string.h>
5885 +#include <linux/errno.h>
5886 +#include <linux/mm.h>
5887 +#include <linux/malloc.h>
5888 +#include <linux/quotaops.h>
5889 +#include <linux/udf_fs.h>
5890 +#endif
5891 +
5892 +static inline int udf_match(int len, const char * const name, struct qstr *qs)
5893 +{
5894 +       if (len != qs->len)
5895 +               return 0;
5896 +       return !memcmp(name, qs->name, len);
5897 +}
5898 +
5899 +int udf_write_fi(struct FileIdentDesc *cfi, struct FileIdentDesc *sfi,
5900 +       struct udf_fileident_bh *fibh,
5901 +       Uint8 *impuse, Uint8 *fileident)
5902 +{
5903 +       Uint16 crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
5904 +       Uint16 crc;
5905 +       Uint8 checksum = 0;
5906 +       int i;
5907 +       int offset;
5908 +       Uint16 liu = le16_to_cpu(cfi->lengthOfImpUse);
5909 +       Uint8 lfi = cfi->lengthFileIdent;
5910 +       int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
5911 +               sizeof(struct FileIdentDesc);
5912 +
5913 +
5914 +       offset = fibh->soffset + sizeof(struct FileIdentDesc);
5915 +
5916 +       if (impuse)
5917 +       {
5918 +               if (offset + liu < 0)
5919 +                       memcpy((Uint8 *)sfi->impUse, impuse, liu);
5920 +               else if (offset >= 0)
5921 +                       memcpy(fibh->ebh->b_data + offset, impuse, liu);
5922 +               else
5923 +               {
5924 +                       memcpy((Uint8 *)sfi->impUse, impuse, -offset);
5925 +                       memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
5926 +               }
5927 +       }
5928 +
5929 +       offset += liu;
5930 +
5931 +       if (fileident)
5932 +       {
5933 +               if (offset + lfi < 0)
5934 +                       memcpy((Uint8 *)sfi->fileIdent + liu, fileident, lfi);
5935 +               else if (offset >= 0)
5936 +                       memcpy(fibh->ebh->b_data + offset, fileident, lfi);
5937 +               else
5938 +               {
5939 +                       memcpy((Uint8 *)sfi->fileIdent + liu, fileident, -offset);
5940 +                       memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
5941 +               }
5942 +       }
5943 +
5944 +       offset += lfi;
5945 +
5946 +       if (offset + padlen < 0)
5947 +               memset((Uint8 *)sfi->padding + liu + lfi, 0x00, padlen);
5948 +       else if (offset >= 0)
5949 +               memset(fibh->ebh->b_data + offset, 0x00, padlen);
5950 +       else
5951 +       {
5952 +               memset((Uint8 *)sfi->padding + liu + lfi, 0x00, -offset);
5953 +               memset(fibh->ebh->b_data, 0x00, padlen + offset);
5954 +       }
5955 +
5956 +       crc = udf_crc((Uint8 *)cfi + sizeof(tag), sizeof(struct FileIdentDesc) -
5957 +               sizeof(tag), 0);
5958 +
5959 +       if (fibh->sbh == fibh->ebh)
5960 +               crc = udf_crc((Uint8 *)sfi->impUse,
5961 +                       crclen + sizeof(tag) - sizeof(struct FileIdentDesc), crc);
5962 +       else if (sizeof(struct FileIdentDesc) >= -fibh->soffset)
5963 +               crc = udf_crc(fibh->ebh->b_data + sizeof(struct FileIdentDesc) + fibh->soffset,
5964 +                       crclen + sizeof(tag) - sizeof(struct FileIdentDesc), crc);
5965 +       else
5966 +       {
5967 +               crc = udf_crc((Uint8 *)sfi->impUse,
5968 +                       -fibh->soffset - sizeof(struct FileIdentDesc), crc);
5969 +               crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
5970 +       }
5971 +
5972 +       cfi->descTag.descCRC = cpu_to_le32(crc);
5973 +       cfi->descTag.descCRCLength = cpu_to_le16(crclen);
5974 +
5975 +       for (i=0; i<16; i++)
5976 +               if (i != 4)
5977 +                       checksum += ((Uint8 *)&cfi->descTag)[i];
5978 +
5979 +       cfi->descTag.tagChecksum = checksum;
5980 +       if (sizeof(struct FileIdentDesc) <= -fibh->soffset)
5981 +               memcpy((Uint8 *)sfi, (Uint8 *)cfi, sizeof(struct FileIdentDesc));
5982 +       else
5983 +       {
5984 +               memcpy((Uint8 *)sfi, (Uint8 *)cfi, -fibh->soffset);
5985 +               memcpy(fibh->ebh->b_data, (Uint8 *)cfi - fibh->soffset,
5986 +                       sizeof(struct FileIdentDesc) + fibh->soffset);
5987 +       }
5988 +
5989 +       if (fibh->sbh != fibh->ebh)
5990 +               mark_buffer_dirty(fibh->ebh, 1);
5991 +       mark_buffer_dirty(fibh->sbh, 1);
5992 +       return 0;
5993 +}
5994 +
5995 +static struct FileIdentDesc *
5996 +udf_find_entry(struct inode *dir, struct dentry *dentry,
5997 +       struct udf_fileident_bh *fibh,
5998 +       struct FileIdentDesc *cfi)
5999 +{
6000 +       struct FileIdentDesc *fi=NULL;
6001 +       int f_pos, block;
6002 +       int flen;
6003 +       char fname[255];
6004 +       char *nameptr;
6005 +       Uint8 lfi;
6006 +       Uint16 liu;
6007 +       int size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
6008 +       lb_addr bloc, eloc;
6009 +       Uint32 extoffset, elen, offset;
6010 +       struct buffer_head *bh = NULL;
6011 +
6012 +       if (!dir)
6013 +               return NULL;
6014 +
6015 +       f_pos = (udf_ext0_offset(dir) >> 2);
6016 +
6017 +       fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
6018 +       if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
6019 +               &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
6020 +       {
6021 +               block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
6022 +               if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
6023 +               {
6024 +                       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
6025 +                               extoffset -= sizeof(short_ad);
6026 +                       else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
6027 +                               extoffset -= sizeof(long_ad);
6028 +               }
6029 +               else
6030 +                       offset = 0;
6031 +       }
6032 +       else
6033 +       {
6034 +               udf_release_data(bh);
6035 +               return NULL;
6036 +       }
6037 +
6038 +       if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
6039 +       {
6040 +               udf_debug("udf_tread failed: block=%d\n", block);
6041 +               udf_release_data(bh);
6042 +               return NULL;
6043 +       }
6044 +
6045 +       while ( (f_pos < size) )
6046 +       {
6047 +               fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
6048 +
6049 +               if (!fi)
6050 +               {
6051 +                       if (fibh->sbh != fibh->ebh)
6052 +                               udf_release_data(fibh->ebh);
6053 +                       udf_release_data(fibh->sbh);
6054 +                       udf_release_data(bh);
6055 +                       return NULL;
6056 +               }
6057 +
6058 +               liu = le16_to_cpu(cfi->lengthOfImpUse);
6059 +               lfi = cfi->lengthFileIdent;
6060 +
6061 +               if (fibh->sbh == fibh->ebh)
6062 +               {
6063 +                       nameptr = fi->fileIdent + liu;
6064 +               }
6065 +               else
6066 +               {
6067 +                       int poffset;    /* Unpaded ending offset */
6068 +
6069 +                       poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
6070 +
6071 +                       if (poffset >= lfi)
6072 +                               nameptr = (Uint8 *)(fibh->ebh->b_data + poffset - lfi);
6073 +                       else
6074 +                       {
6075 +                               nameptr = fname;
6076 +                               memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
6077 +                               memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
6078 +                       }
6079 +               }
6080 +
6081 +               if ( (cfi->fileCharacteristics & FILE_DELETED) != 0 )
6082 +               {
6083 +                       if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) )
6084 +                               continue;
6085 +               }
6086 +           
6087 +               if ( (cfi->fileCharacteristics & FILE_HIDDEN) != 0 )
6088 +               {
6089 +                       if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) )
6090 +                               continue;
6091 +               }
6092 +
6093 +               if (!lfi)
6094 +                       continue;
6095 +
6096 +               if ((flen = udf_get_filename(nameptr, fname, lfi)))
6097 +               {
6098 +                       if (udf_match(flen, fname, &(dentry->d_name)))
6099 +                       {
6100 +                               udf_release_data(bh);
6101 +                               return fi;
6102 +                       }
6103 +               }
6104 +       }
6105 +       if (fibh->sbh != fibh->ebh)
6106 +               udf_release_data(fibh->ebh);
6107 +       udf_release_data(fibh->sbh);
6108 +       udf_release_data(bh);
6109 +       return NULL;
6110 +}
6111 +
6112 +/*
6113 + * udf_lookup
6114 + *
6115 + * PURPOSE
6116 + *     Look-up the inode for a given name.
6117 + *
6118 + * DESCRIPTION
6119 + *     Required - lookup_dentry() will return -ENOTDIR if this routine is not
6120 + *     available for a directory. The filesystem is useless if this routine is
6121 + *     not available for at least the filesystem's root directory.
6122 + *
6123 + *     This routine is passed an incomplete dentry - it must be completed by
6124 + *     calling d_add(dentry, inode). If the name does not exist, then the
6125 + *     specified inode must be set to null. An error should only be returned
6126 + *     when the lookup fails for a reason other than the name not existing.
6127 + *     Note that the directory inode semaphore is held during the call.
6128 + *
6129 + *     Refer to lookup_dentry() in fs/namei.c
6130 + *     lookup_dentry() -> lookup() -> real_lookup() -> .
6131 + *
6132 + * PRE-CONDITIONS
6133 + *     dir                     Pointer to inode of parent directory.
6134 + *     dentry                  Pointer to dentry to complete.
6135 + *
6136 + * POST-CONDITIONS
6137 + *     <return>                Zero on success.
6138 + *
6139 + * HISTORY
6140 + *     July 1, 1997 - Andrew E. Mileski
6141 + *     Written, tested, and released.
6142 + */
6143 +
6144 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
6145 +int
6146 +#else
6147 +struct dentry *
6148 +#endif
6149 +udf_lookup(struct inode *dir, struct dentry *dentry)
6150 +{
6151 +       struct inode *inode = NULL;
6152 +       struct FileIdentDesc cfi, *fi;
6153 +       struct udf_fileident_bh fibh;
6154 +
6155 +       if (dentry->d_name.len > UDF_NAME_LEN)
6156 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
6157 +               return -ENAMETOOLONG;
6158 +#else
6159 +               return ERR_PTR(-ENAMETOOLONG);
6160 +#endif
6161 +
6162 +#ifdef UDF_RECOVERY
6163 +       /* temporary shorthand for specifying files by inode number */
6164 +       if (!strncmp(dentry->d_name.name, ".B=", 3) )
6165 +       {
6166 +               lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) };
6167 +               inode = udf_iget(dir->i_sb, lb);
6168 +               if (!inode)
6169 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
6170 +                       return -EACCES;
6171 +#else
6172 +                       return ERR_PTR(-EACCES);
6173 +#endif
6174 +       }
6175 +       else
6176 +#endif /* UDF_RECOVERY */
6177 +
6178 +       if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi)))
6179 +       {
6180 +               if (fibh.sbh != fibh.ebh)
6181 +                       udf_release_data(fibh.ebh);
6182 +               udf_release_data(fibh.sbh);
6183 +
6184 +               inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
6185 +               if ( !inode )
6186 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
6187 +                       return -EACCES;
6188 +#else
6189 +                       return ERR_PTR(-EACCES);
6190 +#endif
6191 +       }
6192 +       d_add(dentry, inode);
6193 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
6194 +       return 0;
6195 +#else
6196 +       return NULL;
6197 +#endif
6198 +}
6199 +
6200 +static struct FileIdentDesc *
6201 +udf_add_entry(struct inode *dir, struct dentry *dentry,
6202 +       struct udf_fileident_bh *fibh,
6203 +       struct FileIdentDesc *cfi, int *err)
6204 +{
6205 +       struct super_block *sb;
6206 +       struct FileIdentDesc *fi=NULL;
6207 +       struct ustr unifilename;
6208 +       char name[UDF_NAME_LEN], fname[UDF_NAME_LEN];
6209 +       int namelen;
6210 +       int f_pos;
6211 +       int flen;
6212 +       char *nameptr;
6213 +       int size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
6214 +       int nfidlen;
6215 +       Uint8 lfi;
6216 +       Uint16 liu;
6217 +       int block;
6218 +       lb_addr bloc, eloc;
6219 +       Uint32 extoffset, elen, offset;
6220 +       struct buffer_head *bh = NULL;
6221 +
6222 +       if (!dir || !dir->i_nlink)
6223 +               return NULL;
6224 +       sb = dir->i_sb;
6225 +
6226 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6227 +       if (dentry->d_name.len >= UDF_NAME_LEN)
6228 +       {
6229 +               *err = -ENAMETOOLONG;
6230 +               return NULL;
6231 +       }
6232 +#endif
6233 +
6234 +       if (dentry->d_name.len)
6235 +       {
6236 +               if (!dentry->d_name.len)
6237 +               {
6238 +                       *err = -EINVAL;
6239 +                       return NULL;
6240 +               }
6241 +
6242 +               if ( !(udf_char_to_ustr(&unifilename, dentry->d_name.name, dentry->d_name.len)) )
6243 +               {
6244 +                       *err = -ENAMETOOLONG;
6245 +                       return NULL;
6246 +               }
6247 +
6248 +               if ( !(namelen = udf_UTF8toCS0(name, &unifilename, UDF_NAME_LEN)) )
6249 +               {
6250 +                       *err = -ENAMETOOLONG;
6251 +                       return NULL;
6252 +               }
6253 +       }
6254 +       else
6255 +               namelen = 0;
6256 +
6257 +       nfidlen = (sizeof(struct FileIdentDesc) + namelen + 3) & ~3;
6258 +
6259 +       f_pos = (udf_ext0_offset(dir) >> 2);
6260 +
6261 +       fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
6262 +       if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
6263 +               &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
6264 +       {
6265 +               block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
6266 +               if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
6267 +               {
6268 +                       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
6269 +                               extoffset -= sizeof(short_ad);
6270 +                       else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
6271 +                               extoffset -= sizeof(long_ad);
6272 +               }
6273 +               else
6274 +                       offset = 0;
6275 +
6276 +               if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
6277 +               {
6278 +                       udf_release_data(bh);
6279 +                       *err = -EIO;
6280 +                       return NULL;
6281 +               }
6282 +       
6283 +               block = UDF_I_LOCATION(dir).logicalBlockNum;
6284 +       
6285 +               while ( (f_pos < size) )
6286 +               {
6287 +                       fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
6288 +       
6289 +                       if (!fi)
6290 +                       {
6291 +                               if (fibh->sbh != fibh->ebh)
6292 +                                       udf_release_data(fibh->ebh);
6293 +                               udf_release_data(fibh->sbh);
6294 +                               udf_release_data(bh);
6295 +                               *err = -EIO;
6296 +                               return NULL;
6297 +                       }
6298 +       
6299 +                       liu = le16_to_cpu(cfi->lengthOfImpUse);
6300 +                       lfi = cfi->lengthFileIdent;
6301 +       
6302 +                       if (fibh->sbh == fibh->ebh)
6303 +                               nameptr = fi->fileIdent + liu;
6304 +                       else
6305 +                       {
6306 +                               int poffset;    /* Unpaded ending offset */
6307 +       
6308 +                               poffset = fibh->soffset + sizeof(struct FileIdentDesc) + liu + lfi;
6309 +       
6310 +                               if (poffset >= lfi)
6311 +                                       nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
6312 +                               else
6313 +                               {
6314 +                                       nameptr = fname;
6315 +                                       memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
6316 +                                       memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
6317 +                               }
6318 +                       }
6319 +       
6320 +                       if ( (cfi->fileCharacteristics & FILE_DELETED) != 0 )
6321 +                       {
6322 +                               if (((sizeof(struct FileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
6323 +                               {
6324 +                                       udf_release_data(bh);
6325 +                                       cfi->descTag.tagSerialNum = cpu_to_le16(1);
6326 +                                       cfi->fileVersionNum = cpu_to_le16(1);
6327 +                                       cfi->fileCharacteristics = 0;
6328 +                                       cfi->lengthFileIdent = namelen;
6329 +                                       cfi->lengthOfImpUse = cpu_to_le16(0);
6330 +                                       if (!udf_write_fi(cfi, fi, fibh, NULL, name))
6331 +                                               return fi;
6332 +                                       else
6333 +                                       {
6334 +                                               *err = -EIO;
6335 +                                               return NULL;
6336 +                                       }
6337 +                               }
6338 +                       }
6339 +       
6340 +                       if (!lfi)
6341 +                               continue;
6342 +       
6343 +                       if ((flen = udf_get_filename(nameptr, fname, lfi)))
6344 +                       {
6345 +                               if (udf_match(flen, fname, &(dentry->d_name)))
6346 +                               {
6347 +                                       if (fibh->sbh != fibh->ebh)
6348 +                                               udf_release_data(fibh->ebh);
6349 +                                       udf_release_data(fibh->sbh);
6350 +                                       udf_release_data(bh);
6351 +                                       *err = -EEXIST;
6352 +                                       return NULL;
6353 +                               }
6354 +                       }
6355 +               }
6356 +       }
6357 +       else
6358 +       {
6359 +               block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0);
6360 +               if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
6361 +               {
6362 +                       fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize);
6363 +                       fibh->soffset = fibh->eoffset = udf_file_entry_alloc_offset(dir);
6364 +               }
6365 +               else
6366 +               {
6367 +                       fibh->sbh = fibh->ebh = NULL;
6368 +                       fibh->soffset = fibh->eoffset = sb->s_blocksize;
6369 +               }
6370 +       }
6371 +
6372 +       f_pos += nfidlen;
6373 +
6374 +       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB &&
6375 +               sb->s_blocksize - fibh->eoffset < nfidlen)
6376 +       {
6377 +               udf_release_data(bh);
6378 +               bh = NULL;
6379 +               fibh->soffset -= udf_ext0_offset(dir);
6380 +               fibh->eoffset -= udf_ext0_offset(dir);
6381 +               f_pos -= (udf_ext0_offset(dir) >> 2);
6382 +               if (fibh->sbh != fibh->ebh)
6383 +                       udf_release_data(fibh->ebh);
6384 +               udf_release_data(fibh->sbh);
6385 +               if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
6386 +                       return NULL;
6387 +               bloc = UDF_I_LOCATION(dir);
6388 +               eloc.logicalBlockNum = block;
6389 +               eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
6390 +               elen = dir->i_sb->s_blocksize;
6391 +               extoffset = udf_file_entry_alloc_offset(dir);
6392 +               if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
6393 +                       extoffset += sizeof(short_ad);
6394 +               else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
6395 +                       extoffset += sizeof(long_ad);
6396 +       }
6397 +
6398 +       if (sb->s_blocksize - fibh->eoffset >= nfidlen)
6399 +       {
6400 +               fibh->soffset = fibh->eoffset;
6401 +               fibh->eoffset += nfidlen;
6402 +               if (fibh->sbh != fibh->ebh)
6403 +               {
6404 +                       udf_release_data(fibh->sbh);
6405 +                       fibh->sbh = fibh->ebh;
6406 +               }
6407 +
6408 +               if (UDF_I_ALLOCTYPE(dir) != ICB_FLAG_AD_IN_ICB)
6409 +                       block = eloc.logicalBlockNum + ((elen - 1) >>
6410 +                               dir->i_sb->s_blocksize_bits);
6411 +               else
6412 +                       block = UDF_I_LOCATION(dir).logicalBlockNum;
6413 +                               
6414 +               fi = (struct FileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
6415 +       }
6416 +       else
6417 +       {
6418 +               fibh->soffset = fibh->eoffset - sb->s_blocksize;
6419 +               fibh->eoffset += nfidlen - sb->s_blocksize;
6420 +               if (fibh->sbh != fibh->ebh)
6421 +               {
6422 +                       udf_release_data(fibh->sbh);
6423 +                       fibh->sbh = fibh->ebh;
6424 +               }
6425 +
6426 +               block = eloc.logicalBlockNum + ((elen - 1) >>
6427 +                       dir->i_sb->s_blocksize_bits);
6428 +
6429 +               if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
6430 +               {
6431 +                       udf_release_data(bh);
6432 +                       udf_release_data(fibh->sbh);
6433 +                       return NULL;
6434 +               }
6435 +
6436 +               if (!(fibh->soffset))
6437 +               {
6438 +                       if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) ==
6439 +                               EXTENT_RECORDED_ALLOCATED)
6440 +                       {
6441 +                               block = eloc.logicalBlockNum + ((elen - 1) >>
6442 +                                       dir->i_sb->s_blocksize_bits);
6443 +                       }
6444 +                       else
6445 +                               block ++;
6446 +
6447 +                       udf_release_data(fibh->sbh);
6448 +                       fibh->sbh = fibh->ebh;
6449 +                       fi = (struct FileIdentDesc *)(fibh->sbh->b_data);
6450 +               }
6451 +               else
6452 +               {
6453 +                       fi = (struct FileIdentDesc *)
6454 +                               (fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
6455 +               }
6456 +       }
6457 +
6458 +       memset(cfi, 0, sizeof(struct FileIdentDesc));
6459 +       udf_new_tag((char *)cfi, TID_FILE_IDENT_DESC, 2, 1, block, sizeof(tag));
6460 +       cfi->fileVersionNum = cpu_to_le16(1);
6461 +       cfi->lengthFileIdent = namelen;
6462 +       cfi->lengthOfImpUse = cpu_to_le16(0);
6463 +       if (!udf_write_fi(cfi, fi, fibh, NULL, name))
6464 +       {
6465 +               udf_release_data(bh);
6466 +               dir->i_size += nfidlen;
6467 +               if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
6468 +                       UDF_I_LENALLOC(dir) += nfidlen;
6469 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6470 +               dir->i_version = ++event;
6471 +#else
6472 +               dir->i_version = ++global_event;
6473 +#endif
6474 +               mark_inode_dirty(dir);
6475 +               return fi;
6476 +       }
6477 +       else
6478 +       {
6479 +               udf_release_data(bh);
6480 +               if (fibh->sbh != fibh->ebh)
6481 +                       udf_release_data(fibh->ebh);
6482 +               udf_release_data(fibh->sbh);
6483 +               *err = -EIO;
6484 +               return NULL;
6485 +       }
6486 +}
6487 +
6488 +static int udf_delete_entry(struct FileIdentDesc *fi,
6489 +       struct udf_fileident_bh *fibh,
6490 +       struct FileIdentDesc *cfi)
6491 +{
6492 +       cfi->fileCharacteristics |= FILE_DELETED;
6493 +       return udf_write_fi(cfi, fi, fibh, NULL, NULL);
6494 +}
6495 +
6496 +int udf_create(struct inode *dir, struct dentry *dentry, int mode)
6497 +{
6498 +       struct udf_fileident_bh fibh;
6499 +       struct inode *inode;
6500 +       struct FileIdentDesc cfi, *fi;
6501 +       int err;
6502 +
6503 +       inode = udf_new_inode(dir, mode, &err);
6504 +       if (!inode)
6505 +       {
6506 +               udf_debug("udf_new_inode failure, err=%d\n", err);
6507 +               return err;
6508 +       }
6509 +
6510 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
6511 +               inode->i_op = &udf_file_inode_operations_adinicb;
6512 +       else
6513 +               inode->i_op = &udf_file_inode_operations;
6514 +       inode->i_mode = mode;
6515 +       mark_inode_dirty(inode);
6516 +
6517 +       if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
6518 +       {
6519 +               udf_debug("udf_add_entry failure!\n");
6520 +               inode->i_nlink --;
6521 +               mark_inode_dirty(inode);
6522 +               iput(inode);
6523 +               return err;
6524 +       }
6525 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
6526 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
6527 +       *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
6528 +               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
6529 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
6530 +       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
6531 +       {
6532 +               mark_inode_dirty(dir);
6533 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6534 +               dir->i_version = ++event;
6535 +#else
6536 +               dir->i_version = ++global_event;
6537 +#endif
6538 +       }
6539 +       if (fibh.sbh != fibh.ebh)
6540 +               udf_release_data(fibh.ebh);
6541 +       udf_release_data(fibh.sbh);
6542 +       d_instantiate(dentry, inode);
6543 +       return 0;
6544 +}
6545 +
6546 +int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
6547 +{
6548 +       struct inode * inode;
6549 +       struct udf_fileident_bh fibh;
6550 +       int err;
6551 +       struct FileIdentDesc cfi, *fi;
6552 +
6553 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6554 +       err = -ENAMETOOLONG;
6555 +       if (dentry->d_name.len >= UDF_NAME_LEN)
6556 +               goto out;
6557 +#endif
6558 +
6559 +       err = -EIO;
6560 +       inode = udf_new_inode(dir, mode, &err);
6561 +       if (!inode)
6562 +               goto out;
6563 +
6564 +       inode->i_uid = current->fsuid;
6565 +       inode->i_mode = mode;
6566 +       inode->i_op = NULL;
6567 +       if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
6568 +       {
6569 +               udf_debug("udf_add_entry failure!\n");
6570 +               inode->i_nlink --;
6571 +               mark_inode_dirty(inode);
6572 +               iput(inode);
6573 +               return err;
6574 +       }
6575 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
6576 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
6577 +       *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
6578 +               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
6579 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
6580 +       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
6581 +       {
6582 +               mark_inode_dirty(dir);
6583 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6584 +               dir->i_version = ++event;
6585 +#else
6586 +               dir->i_version = ++global_event;
6587 +#endif
6588 +       }
6589 +       if (S_ISREG(inode->i_mode))
6590 +       {
6591 +               if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
6592 +                       inode->i_op = &udf_file_inode_operations_adinicb;
6593 +               else
6594 +                       inode->i_op = &udf_file_inode_operations;
6595 +       }
6596 +       else if (S_ISCHR(inode->i_mode))
6597 +       {
6598 +               inode->i_op = &chrdev_inode_operations;
6599 +       } 
6600 +       else if (S_ISBLK(inode->i_mode))
6601 +       {
6602 +               inode->i_op = &blkdev_inode_operations;
6603 +       }
6604 +       else if (S_ISFIFO(inode->i_mode))
6605 +       {
6606 +               init_fifo(inode);
6607 +       }
6608 +       if (S_ISBLK(mode) || S_ISCHR(mode))
6609 +               inode->i_rdev = to_kdev_t(rdev);
6610 +       mark_inode_dirty(inode);
6611 +
6612 +       if (fibh.sbh != fibh.ebh)
6613 +               udf_release_data(fibh.ebh);
6614 +       udf_release_data(fibh.sbh);
6615 +       d_instantiate(dentry, inode);
6616 +       err = 0;
6617 +out:
6618 +       return err;
6619 +}
6620 +
6621 +int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
6622 +{
6623 +       struct inode * inode;
6624 +       struct udf_fileident_bh fibh;
6625 +       int err;
6626 +       struct FileIdentDesc cfi, *fi;
6627 +
6628 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6629 +       err = -ENAMETOOLONG;
6630 +       if (dentry->d_name.len >= UDF_NAME_LEN)
6631 +               goto out;
6632 +#endif
6633 +
6634 +       err = -EMLINK;
6635 +       if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1)
6636 +               goto out;
6637 +
6638 +       err = -EIO;
6639 +       inode = udf_new_inode(dir, S_IFDIR, &err);
6640 +       if (!inode)
6641 +               goto out;
6642 +
6643 +       inode->i_op = &udf_dir_inode_operations;
6644 +       if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err)))
6645 +       {
6646 +               inode->i_nlink--;
6647 +               mark_inode_dirty(inode);
6648 +               iput(inode);
6649 +               goto out;
6650 +       }
6651 +       inode->i_nlink = 2;
6652 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
6653 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
6654 +       *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
6655 +               cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
6656 +       cfi.fileCharacteristics = FILE_DIRECTORY | FILE_PARENT;
6657 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
6658 +       udf_release_data(fibh.sbh);
6659 +       inode->i_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask);
6660 +       if (dir->i_mode & S_ISGID)
6661 +               inode->i_mode |= S_ISGID;
6662 +       mark_inode_dirty(inode);
6663 +
6664 +       if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
6665 +       {
6666 +               udf_debug("udf_add_entry failure!\n");
6667 +               inode->i_nlink = 0;
6668 +               mark_inode_dirty(inode);
6669 +               iput(inode);
6670 +               goto out;
6671 +       }
6672 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
6673 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
6674 +       *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
6675 +               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
6676 +       cfi.fileCharacteristics |= FILE_DIRECTORY;
6677 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
6678 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6679 +       dir->i_version = ++event;
6680 +#else
6681 +       dir->i_version = ++global_event;
6682 +#endif
6683 +       dir->i_nlink++;
6684 +       mark_inode_dirty(dir);
6685 +       d_instantiate(dentry, inode);
6686 +       if (fibh.sbh != fibh.ebh)
6687 +               udf_release_data(fibh.ebh);
6688 +       udf_release_data(fibh.sbh);
6689 +       err = 0;
6690 +out:
6691 +       return err;
6692 +}
6693 +
6694 +static int empty_dir(struct inode *dir)
6695 +{
6696 +       struct FileIdentDesc *fi, cfi;
6697 +       struct udf_fileident_bh fibh;
6698 +       int f_pos;
6699 +       int size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
6700 +       int block;
6701 +       lb_addr bloc, eloc;
6702 +       Uint32 extoffset, elen, offset;
6703 +       struct buffer_head *bh = NULL;
6704 +
6705 +       f_pos = (udf_ext0_offset(dir) >> 2);
6706 +
6707 +       fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
6708 +       if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
6709 +               &bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
6710 +       {
6711 +               block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
6712 +               if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
6713 +               {
6714 +                       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
6715 +                               extoffset -= sizeof(short_ad);
6716 +                       else if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_LONG)
6717 +                               extoffset -= sizeof(long_ad);
6718 +               }
6719 +               else
6720 +                       offset = 0;
6721 +       }
6722 +       else
6723 +       {
6724 +               udf_release_data(bh);
6725 +               return 0;
6726 +       }
6727 +
6728 +       if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block, dir->i_sb->s_blocksize)))
6729 +               return 0;
6730 +
6731 +       while ( (f_pos < size) )
6732 +       {
6733 +               fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
6734 +
6735 +               if (!fi)
6736 +               {
6737 +                       if (fibh.sbh != fibh.ebh)
6738 +                               udf_release_data(fibh.ebh);
6739 +                       udf_release_data(fibh.sbh);
6740 +                       udf_release_data(bh);
6741 +                       return 0;
6742 +               }
6743 +
6744 +               if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FILE_DELETED) == 0)
6745 +               {
6746 +                       udf_release_data(bh);
6747 +                       return 0;
6748 +               }
6749 +       }
6750 +       if (fibh.sbh != fibh.ebh)
6751 +               udf_release_data(fibh.ebh);
6752 +       udf_release_data(fibh.sbh);
6753 +       udf_release_data(bh);
6754 +       return 1;
6755 +}
6756 +
6757 +int udf_rmdir(struct inode * dir, struct dentry * dentry)
6758 +{
6759 +       int retval;
6760 +       struct inode * inode;
6761 +       struct udf_fileident_bh fibh;
6762 +       struct FileIdentDesc *fi, cfi;
6763 +
6764 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6765 +       retval = -ENAMETOOLONG;
6766 +       if (dentry->d_name.len >= UDF_NAME_LEN)
6767 +               goto out;
6768 +#endif
6769 +
6770 +       retval = -ENOENT;
6771 +       fi = udf_find_entry(dir, dentry, &fibh, &cfi);
6772 +       if (!fi)
6773 +               goto out;
6774 +
6775 +       inode = dentry->d_inode;
6776 +       DQUOT_INIT(inode);
6777 +
6778 +       retval = -EIO;
6779 +       if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) != inode->i_ino)
6780 +               goto end_rmdir;
6781 +
6782 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6783 +       if (!empty_dir(inode))
6784 +               retval = -ENOTEMPTY;
6785 +       else if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
6786 +               inode->i_ino)
6787 +       {
6788 +               retval = -ENOENT;
6789 +       }
6790 +       else
6791 +       {
6792 +               retval = udf_delete_entry(fi, &fibh, &cfi);
6793 +               dir->i_version = ++event;
6794 +       }
6795 +#else
6796 +       retval = -ENOTEMPTY;
6797 +       if (!empty_dir(inode))
6798 +               goto end_rmdir;
6799 +       retval = udf_delete_entry(fi, &fibh, &cfi);
6800 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6801 +       dir->i_version = ++event;
6802 +#else
6803 +       dir->i_version = ++global_event;
6804 +#endif
6805 +#endif
6806 +       if (retval)
6807 +               goto end_rmdir;
6808 +       if (inode->i_nlink != 2)
6809 +               udf_warning(inode->i_sb, "udf_rmdir",
6810 +                       "empty directory has nlink != 2 (%d)",
6811 +                       inode->i_nlink);
6812 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
6813 +       inode->i_version = ++event;
6814 +#else
6815 +       inode->i_version = ++global_event;
6816 +#endif
6817 +       inode->i_nlink = 0;
6818 +       inode->i_size = 0;
6819 +       mark_inode_dirty(inode);
6820 +       dir->i_nlink --;
6821 +       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
6822 +       UDF_I_UCTIME(inode) = UDF_I_UCTIME(dir) = UDF_I_UMTIME(dir) = CURRENT_UTIME;
6823 +       mark_inode_dirty(dir);
6824 +       d_delete(dentry);
6825 +
6826 +end_rmdir:
6827 +       if (fibh.sbh != fibh.ebh)
6828 +               udf_release_data(fibh.ebh);
6829 +       udf_release_data(fibh.sbh);
6830 +out:
6831 +       return retval;
6832 +}
6833 +
6834 +int udf_unlink(struct inode * dir, struct dentry * dentry)
6835 +{
6836 +       int retval;
6837 +       struct inode * inode;
6838 +       struct udf_fileident_bh fibh;
6839 +       struct FileIdentDesc *fi;
6840 +       struct FileIdentDesc cfi;
6841 +
6842 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
6843 +       retval = -ENAMETOOLONG;
6844 +       if (dentry->d_name.len >= UDF_NAME_LEN)
6845 +               goto out;
6846 +#endif
6847 +
6848 +       retval = -ENOENT;
6849 +       fi = udf_find_entry(dir, dentry, &fibh, &cfi);
6850 +       if (!fi)
6851 +               goto out;
6852 +
6853 +       inode = dentry->d_inode;
6854 +       DQUOT_INIT(inode);
6855 +
6856 +       retval = -EIO;
6857 +
6858 +       if (udf_get_lb_pblock(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation), 0) !=
6859 +               inode->i_ino)
6860 +       {
6861 +               goto end_unlink;
6862 +       }
6863 +
6864 +       if (!inode->i_nlink)
6865 +       {
6866 +               udf_debug("Deleting nonexistent file (%lu), %d\n",
6867 +                       inode->i_ino, inode->i_nlink);
6868 +               inode->i_nlink = 1;
6869 +       }
6870 +       retval = udf_delete_entry(fi, &fibh, &cfi);
6871 +       if (retval)
6872 +               goto end_unlink;
6873 +       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
6874 +       UDF_I_UCTIME(dir) = UDF_I_UMTIME(dir) = CURRENT_UTIME;
6875 +       mark_inode_dirty(dir);
6876 +       inode->i_nlink--;
6877 +       mark_inode_dirty(inode);
6878 +       inode->i_ctime = dir->i_ctime;
6879 +       retval = 0;
6880 +       d_delete(dentry);       /* This also frees the inode */
6881 +
6882 +end_unlink:
6883 +       if (fibh.sbh != fibh.ebh)
6884 +               udf_release_data(fibh.ebh);
6885 +       udf_release_data(fibh.sbh);
6886 +out:
6887 +       return retval;
6888 +}
6889 +
6890 +int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname)
6891 +{
6892 +       struct inode * inode;
6893 +       struct PathComponent *pc;
6894 +       char *compstart;
6895 +       struct udf_fileident_bh fibh;
6896 +       struct buffer_head *bh = NULL;
6897 +       int eoffset, elen = 0;
6898 +       struct FileIdentDesc *fi;
6899 +       struct FileIdentDesc cfi;
6900 +       char *ea;
6901 +       int err;
6902 +       int block;
6903 +
6904 +       if (!(inode = udf_new_inode(dir, S_IFLNK, &err)))
6905 +               goto out;
6906 +
6907 +       inode->i_mode = S_IFLNK | S_IRWXUGO;
6908 +       inode->i_op = &udf_symlink_inode_operations;
6909 +
6910 +       if (UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
6911 +       {
6912 +               struct buffer_head *bh = NULL;
6913 +               lb_addr bloc, eloc;
6914 +               Uint32 elen, extoffset;
6915 +
6916 +               block = udf_new_block(inode,
6917 +                       UDF_I_LOCATION(inode).partitionReferenceNum,
6918 +                       UDF_I_LOCATION(inode).logicalBlockNum, &err);
6919 +               if (!block)
6920 +                       goto out_no_entry;
6921 +               bloc = UDF_I_LOCATION(inode);
6922 +               eloc.logicalBlockNum = block;
6923 +               eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
6924 +               elen = inode->i_sb->s_blocksize;
6925 +               extoffset = udf_file_entry_alloc_offset(inode);
6926 +               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
6927 +               udf_release_data(bh);
6928 +
6929 +               inode->i_blocks = inode->i_sb->s_blocksize / 512;
6930 +               block = udf_get_pblock(inode->i_sb, block,
6931 +                       UDF_I_LOCATION(inode).partitionReferenceNum, 0);
6932 +       }
6933 +       else
6934 +               block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
6935 +
6936 +       bh = udf_tread(inode->i_sb, block, inode->i_sb->s_blocksize);
6937 +       ea = bh->b_data + udf_ext0_offset(inode);
6938 +
6939 +       eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
6940 +       pc = (struct PathComponent *)ea;
6941 +
6942 +       if (*symname == '/')
6943 +       {
6944 +               do
6945 +               {
6946 +                       symname++;
6947 +               } while (*symname == '/');
6948 +
6949 +               pc->componentType = 1;
6950 +               pc->lengthComponentIdent = 0;
6951 +               pc->componentFileVersionNum = 0;
6952 +               pc += sizeof(struct PathComponent);
6953 +               elen += sizeof(struct PathComponent);
6954 +       }
6955 +
6956 +       err = -ENAMETOOLONG;
6957 +
6958 +       while (*symname)
6959 +       {
6960 +               if (elen + sizeof(struct PathComponent) > eoffset)
6961 +                       goto out_no_entry;
6962 +
6963 +               pc = (struct PathComponent *)(ea + elen);
6964 +
6965 +               compstart = (char *)symname;
6966 +
6967 +               do
6968 +               {
6969 +                       symname++;
6970 +               } while (*symname && *symname != '/');
6971 +
6972 +               pc->componentType = 5;
6973 +               pc->lengthComponentIdent = 0;
6974 +               pc->componentFileVersionNum = 0;
6975 +               if (pc->componentIdent[0] == '.')
6976 +               {
6977 +                       if (pc->lengthComponentIdent == 1)
6978 +                               pc->componentType = 4;
6979 +                       else if (pc->lengthComponentIdent == 2 && pc->componentIdent[1] == '.')
6980 +                               pc->componentType = 3;
6981 +               }
6982 +
6983 +               if (pc->componentType == 5)
6984 +               {
6985 +                       if (elen + sizeof(struct PathComponent) + symname - compstart > eoffset)
6986 +                               goto out_no_entry;
6987 +                       else
6988 +                               pc->lengthComponentIdent = symname - compstart;
6989 +
6990 +                       memcpy(pc->componentIdent, compstart, pc->lengthComponentIdent);
6991 +               }
6992 +
6993 +               elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
6994 +
6995 +               if (*symname)
6996 +               {
6997 +                       do
6998 +                       {
6999 +                               symname++;
7000 +                       } while (*symname == '/');
7001 +               }
7002 +       }
7003 +
7004 +       udf_release_data(bh);
7005 +       inode->i_size = elen;
7006 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
7007 +               UDF_I_LENALLOC(inode) = inode->i_size;
7008 +       mark_inode_dirty(inode);
7009 +
7010 +       if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
7011 +               goto out_no_entry;
7012 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
7013 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
7014 +       if (UDF_SB_LVIDBH(inode->i_sb))
7015 +       {
7016 +               struct LogicalVolHeaderDesc *lvhd;
7017 +               Uint64 uniqueID;
7018 +               lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
7019 +               uniqueID = le64_to_cpu(lvhd->uniqueID);
7020 +               *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
7021 +                       cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
7022 +               if (!(++uniqueID & 0x00000000FFFFFFFFUL))
7023 +                       uniqueID += 16;
7024 +               lvhd->uniqueID = cpu_to_le64(uniqueID);
7025 +               mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb), 1);
7026 +       }
7027 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
7028 +       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
7029 +       {
7030 +               mark_inode_dirty(dir);
7031 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
7032 +               dir->i_version = ++event;
7033 +#else
7034 +               dir->i_version = ++global_event;
7035 +#endif
7036 +       }
7037 +       if (fibh.sbh != fibh.ebh)
7038 +               udf_release_data(fibh.ebh);
7039 +       udf_release_data(fibh.sbh);
7040 +       d_instantiate(dentry, inode);
7041 +       err = 0;
7042 +
7043 +out:
7044 +       return err;
7045 +
7046 +out_no_entry:
7047 +       inode->i_nlink--;
7048 +       mark_inode_dirty(inode);
7049 +       iput(inode);
7050 +       goto out;
7051 +}
7052 +
7053 +int udf_link(struct dentry * old_dentry, struct inode * dir,
7054 +        struct dentry *dentry)
7055 +{
7056 +       struct inode *inode = old_dentry->d_inode;
7057 +       struct udf_fileident_bh fibh;
7058 +       int err;
7059 +       struct FileIdentDesc cfi, *fi;
7060 +
7061 +       if (S_ISDIR(inode->i_mode))
7062 +               return -EPERM;
7063 +
7064 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
7065 +       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7066 +               return -EPERM;
7067 +#endif
7068 +
7069 +       if (inode->i_nlink >= (256<<sizeof(inode->i_nlink))-1)
7070 +               return -EMLINK;
7071 +
7072 +       if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
7073 +               return err;
7074 +       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
7075 +       cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
7076 +       if (UDF_SB_LVIDBH(inode->i_sb))
7077 +       {
7078 +               struct LogicalVolHeaderDesc *lvhd;
7079 +               Uint64 uniqueID;
7080 +               lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
7081 +               uniqueID = le64_to_cpu(lvhd->uniqueID);
7082 +               *(Uint32 *)((struct ADImpUse *)cfi.icb.impUse)->impUse =
7083 +                       cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
7084 +               if (!(++uniqueID & 0x00000000FFFFFFFFUL))
7085 +                       uniqueID += 16;
7086 +               lvhd->uniqueID = cpu_to_le64(uniqueID);
7087 +               mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb), 1);
7088 +       }
7089 +       udf_write_fi(&cfi, fi, &fibh, NULL, NULL);
7090 +       if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_IN_ICB)
7091 +       {
7092 +               mark_inode_dirty(dir);
7093 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
7094 +               dir->i_version = ++event;
7095 +#else
7096 +               dir->i_version = ++global_event;
7097 +#endif
7098 +       }
7099 +       if (fibh.sbh != fibh.ebh)
7100 +               udf_release_data(fibh.ebh);
7101 +       udf_release_data(fibh.sbh);
7102 +       inode->i_nlink ++;
7103 +       inode->i_ctime = CURRENT_TIME;
7104 +       UDF_I_UCTIME(inode) = CURRENT_UTIME;
7105 +       mark_inode_dirty(inode);
7106 +       inode->i_count ++;
7107 +       d_instantiate(dentry, inode);
7108 +       return 0;
7109 +}
7110 +
7111 +
7112 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
7113 +
7114 +/*
7115 + * rename uses retrying to avoid race-conditions: at least they should be
7116 + * minimal.
7117 + * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
7118 + * checks fail, it tries to restart itself again. Very practical - no changes
7119 + * are done until we know everything works ok.. and then all the changes can be
7120 + * done in one fell swoop when we have claimed all the buffers needed.
7121 + *
7122 + * Anybody can rename anything with this: the permission checks are left to the
7123 + * higher-level routines.
7124 + */
7125 +static int do_udf_rename(struct inode *old_dir, struct dentry *old_dentry,
7126 +       struct inode *new_dir, struct dentry *new_dentry)
7127 +{
7128 +       struct inode * old_inode, * new_inode;
7129 +       struct udf_fileident_bh ofibh, nfibh;
7130 +       struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
7131 +       struct buffer_head *dir_bh = NULL;
7132 +       int retval = -ENOENT;
7133 +
7134 +       if (old_dentry->d_name.len > UDF_NAME_LEN)
7135 +               goto end_rename;
7136 +
7137 +       old_inode = old_dentry->d_inode;
7138 +       ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
7139 +       if (!ofi || udf_get_lb_pblock(old_dir->i_sb, lelb_to_cpu(ocfi.icb.extLocation), 0) !=
7140 +               old_inode->i_ino)
7141 +       {
7142 +               goto end_rename;
7143 +       }
7144 +
7145 +       new_inode = new_dentry->d_inode;
7146 +       nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
7147 +       if (nfi)
7148 +       {
7149 +               if (!new_inode)
7150 +               {
7151 +                       if (nfibh.sbh != nfibh.ebh)
7152 +                               udf_release_data(nfibh.ebh);
7153 +                       udf_release_data(nfibh.sbh);
7154 +                       nfi = NULL;
7155 +               }
7156 +               else
7157 +               {
7158 +                       DQUOT_INIT(new_inode);
7159 +               }
7160 +       }
7161 +       retval = 0;
7162 +       if (new_inode == old_inode)
7163 +               goto end_rename;
7164 +       if (S_ISDIR(old_inode->i_mode))
7165 +       {
7166 +               Uint32 offset = udf_ext0_offset(old_inode);
7167 +               retval = -EINVAL;
7168 +               if (is_subdir(new_dentry, old_dentry))
7169 +                       goto end_rename;
7170 +
7171 +               if (new_inode)
7172 +               {
7173 +                       /* Prune any children before testing for busy */
7174 +                       if (new_dentry->d_count > 1)
7175 +                               shrink_dcache_parent(new_dentry);
7176 +                               retval = -EBUSY;
7177 +                               if (new_dentry->d_count > 1)
7178 +                                       goto end_rename;
7179 +                       retval = -ENOTEMPTY;
7180 +                       if (!empty_dir(new_inode))
7181 +                               goto end_rename;
7182 +               }
7183 +               dir_bh = udf_bread(old_inode, 0, 0, &retval);
7184 +               if (!dir_bh)
7185 +                       goto end_rename;
7186 +               dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
7187 +               if (!dir_fi)
7188 +                       goto end_rename;
7189 +               if (udf_get_lb_pblock(old_inode->i_sb, cpu_to_lelb(dir_fi->icb.extLocation), 0) !=
7190 +                       old_dir->i_ino)
7191 +               {
7192 +                       goto end_rename;
7193 +               }
7194 +               retval = -EMLINK;
7195 +               if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1)
7196 +                       goto end_rename;
7197 +       }
7198 +       if (!nfi)
7199 +       {
7200 +               nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
7201 +               if (!nfi)
7202 +                       goto end_rename;
7203 +       }
7204 +       new_dir->i_version = ++event;
7205 +
7206 +       /*
7207 +        * Like most other Unix systems, set the ctime for inodes on a
7208 +        * rename.
7209 +        */
7210 +       old_inode->i_ctime = CURRENT_TIME;
7211 +       UDF_I_UCTIME(old_inode) = CURRENT_UTIME;
7212 +       mark_inode_dirty(old_inode);
7213 +
7214 +       /*
7215 +        * ok, that's it
7216 +        */
7217 +       ncfi.fileVersionNum = ocfi.fileVersionNum;
7218 +       ncfi.fileCharacteristics = ocfi.fileCharacteristics;
7219 +       memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
7220 +       udf_write_fi(&ncfi, nfi, &nfibh, NULL, NULL);
7221 +
7222 +       udf_delete_entry(ofi, &ofibh, &ocfi);
7223 +
7224 +       old_dir->i_version = ++event;
7225 +       if (new_inode)
7226 +       {
7227 +               new_inode->i_nlink--;
7228 +               new_inode->i_ctime = CURRENT_TIME;
7229 +               UDF_I_UCTIME(new_inode) = CURRENT_UTIME;
7230 +               mark_inode_dirty(new_inode);
7231 +       }
7232 +       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
7233 +       UDF_I_UCTIME(old_dir) = UDF_I_UMTIME(old_dir) = CURRENT_UTIME;
7234 +       mark_inode_dirty(old_dir);
7235 +
7236 +       if (dir_bh)
7237 +       {
7238 +               dir_fi->icb.extLocation = lelb_to_cpu(UDF_I_LOCATION(new_dir));
7239 +               udf_update_tag((char *)dir_fi, sizeof(struct FileIdentDesc) +
7240 +                       cpu_to_le16(dir_fi->lengthOfImpUse));
7241 +               if (UDF_I_ALLOCTYPE(old_inode) == ICB_FLAG_AD_IN_ICB)
7242 +               {
7243 +                       mark_inode_dirty(old_inode);
7244 +                       old_inode->i_version = ++event;
7245 +               }
7246 +               else
7247 +                       mark_buffer_dirty(dir_bh, 1);
7248 +               old_dir->i_nlink --;
7249 +               mark_inode_dirty(old_dir);
7250 +               if (new_inode)
7251 +               {
7252 +                       new_inode->i_nlink --;
7253 +                       mark_inode_dirty(new_inode);
7254 +               }
7255 +               else
7256 +               {
7257 +                       new_dir->i_nlink ++;
7258 +                       mark_inode_dirty(new_dir);
7259 +               }
7260 +       }
7261 +
7262 +       /* Update the dcache */
7263 +       d_move(old_dentry, new_dentry);
7264 +       retval = 0;
7265 +
7266 +end_rename:
7267 +       udf_release_data(dir_bh);
7268 +       if (ofi)
7269 +       {
7270 +               if (ofibh.sbh != ofibh.ebh)
7271 +                       udf_release_data(ofibh.ebh);
7272 +               udf_release_data(ofibh.sbh);
7273 +       }
7274 +       if (nfi)
7275 +       {
7276 +               if (nfibh.sbh != nfibh.ebh)
7277 +                       udf_release_data(nfibh.ebh);
7278 +               udf_release_data(nfibh.sbh);
7279 +       }
7280 +       return retval;
7281 +}
7282 +
7283 +/* Ok, rename also locks out other renames, as they can change the parent of
7284 + * a directory, and we don't want any races. Other races are checked for by
7285 + * "do_rename()", which restarts if there are inconsistencies.
7286 + *
7287 + * Note that there is no race between different filesystems: it's only within
7288 + * the same device that races occur: many renames can happen at once, as long
7289 + * as they are on different partitions.
7290 + *
7291 + * In the udf file system, we use a lock flag stored in the memory
7292 + * super-block.  This way, we really lock other renames only if they occur
7293 + * on the same file system
7294 + */
7295 +
7296 +int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
7297 +       struct inode *new_dir, struct dentry *new_dentry)
7298 +{
7299 +       int result;
7300 +
7301 +       while (UDF_SB_RENAME_LOCK(old_dir->i_sb))
7302 +               sleep_on(&UDF_SB_RENAME_WAIT(old_dir->i_sb));
7303 +       UDF_SB_RENAME_LOCK(old_dir->i_sb) = 1;
7304 +       result = do_udf_rename(old_dir, old_dentry, new_dir, new_dentry);
7305 +       UDF_SB_RENAME_LOCK(old_dir->i_sb) = 0;
7306 +       wake_up(&UDF_SB_RENAME_WAIT(old_dir->i_sb));
7307 +       return result;
7308 +}
7309 +
7310 +#else
7311 +
7312 +/* Anybody can rename anything with this: the permission checks are left to the
7313 + * higher-level routines.
7314 + */
7315 +int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
7316 +       struct inode * new_dir, struct dentry * new_dentry)
7317 +{
7318 +       struct inode * old_inode, * new_inode;
7319 +       struct udf_fileident_bh ofibh, nfibh;
7320 +       struct FileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
7321 +       struct buffer_head *dir_bh = NULL;
7322 +       int retval = -ENOENT;
7323 +
7324 +       old_inode = old_dentry->d_inode;
7325 +       ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi);
7326 +       if (!ofi || udf_get_lb_pblock(old_dir->i_sb, lelb_to_cpu(ocfi.icb.extLocation), 0) !=
7327 +               old_inode->i_ino)
7328 +       {
7329 +               goto end_rename;
7330 +       }
7331 +
7332 +       new_inode = new_dentry->d_inode;
7333 +       nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi);
7334 +       if (nfi)
7335 +       {
7336 +               if (!new_inode)
7337 +               {
7338 +                       if (nfibh.sbh != nfibh.ebh)
7339 +                               udf_release_data(nfibh.ebh);
7340 +                       udf_release_data(nfibh.sbh);
7341 +                       nfi = NULL;
7342 +               }
7343 +               else
7344 +               {
7345 +                       DQUOT_INIT(new_inode);
7346 +               }
7347 +       }
7348 +       if (S_ISDIR(old_inode->i_mode))
7349 +       {
7350 +               Uint32 offset = udf_ext0_offset(old_inode);
7351 +
7352 +               if (new_inode)
7353 +               {
7354 +                       retval = -ENOTEMPTY;
7355 +                       if (!empty_dir(new_inode))
7356 +                               goto end_rename;
7357 +               }
7358 +               retval = -EIO;
7359 +               dir_bh = udf_bread(old_inode, 0, 0, &retval);
7360 +               if (!dir_bh)
7361 +                       goto end_rename;
7362 +               dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
7363 +               if (!dir_fi)
7364 +                       goto end_rename;
7365 +               if (udf_get_lb_pblock(old_inode->i_sb, cpu_to_lelb(dir_fi->icb.extLocation), 0) !=
7366 +                       old_dir->i_ino)
7367 +               {
7368 +                       goto end_rename;
7369 +               }
7370 +               retval = -EMLINK;
7371 +               if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1)
7372 +                       goto end_rename;
7373 +       }
7374 +       if (!nfi)
7375 +       {
7376 +               nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
7377 +               if (!nfi)
7378 +                       goto end_rename;
7379 +       }
7380 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
7381 +       new_dir->i_version = ++event;
7382 +#else
7383 +       new_dir->i_version = ++global_event;
7384 +#endif
7385 +
7386 +       /*
7387 +        * ok, that's it
7388 +        */
7389 +       ncfi.fileVersionNum = ocfi.fileVersionNum;
7390 +       ncfi.fileCharacteristics = ocfi.fileCharacteristics;
7391 +       memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
7392 +       udf_write_fi(&ncfi, nfi, &nfibh, NULL, NULL);
7393 +
7394 +       udf_delete_entry(ofi, &ofibh, &ocfi);
7395 +
7396 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
7397 +       old_dir->i_version = ++event;
7398 +#else
7399 +       old_dir->i_version = ++global_event;
7400 +#endif
7401 +       if (new_inode)
7402 +       {
7403 +               new_inode->i_nlink--;
7404 +               new_inode->i_ctime = CURRENT_TIME;
7405 +               UDF_I_UCTIME(new_inode) = CURRENT_UTIME;
7406 +               mark_inode_dirty(new_inode);
7407 +       }
7408 +       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
7409 +       UDF_I_UCTIME(old_dir) = UDF_I_UMTIME(old_dir) = CURRENT_UTIME;
7410 +       mark_inode_dirty(old_dir);
7411 +
7412 +       if (dir_bh)
7413 +       {
7414 +               dir_fi->icb.extLocation = lelb_to_cpu(UDF_I_LOCATION(new_dir));
7415 +               udf_update_tag((char *)dir_fi, sizeof(struct FileIdentDesc) +
7416 +                       cpu_to_le16(dir_fi->lengthOfImpUse));
7417 +               if (UDF_I_ALLOCTYPE(old_inode) == ICB_FLAG_AD_IN_ICB)
7418 +               {
7419 +                       mark_inode_dirty(old_inode);
7420 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,14)
7421 +                       old_inode->i_version = ++event;
7422 +#else
7423 +                       old_inode->i_version = ++global_event;
7424 +#endif
7425 +               }
7426 +               else
7427 +                       mark_buffer_dirty(dir_bh, 1);
7428 +               old_dir->i_nlink --;
7429 +               mark_inode_dirty(old_dir);
7430 +               if (new_inode)
7431 +               {
7432 +                       new_inode->i_nlink --;
7433 +                       mark_inode_dirty(new_inode);
7434 +               }
7435 +               else
7436 +               {
7437 +                       new_dir->i_nlink ++;
7438 +                       mark_inode_dirty(new_dir);
7439 +               }
7440 +       }
7441 +
7442 +       retval = 0;
7443 +
7444 +end_rename:
7445 +       udf_release_data(dir_bh);
7446 +       if (ofi)
7447 +       {
7448 +               if (ofibh.sbh != ofibh.ebh)
7449 +                       udf_release_data(ofibh.ebh);
7450 +               udf_release_data(ofibh.sbh);
7451 +       }
7452 +       if (nfi)
7453 +       {
7454 +               if (nfibh.sbh != nfibh.ebh)
7455 +                       udf_release_data(nfibh.ebh);
7456 +               udf_release_data(nfibh.sbh);
7457 +       }
7458 +       return retval;
7459 +}
7460 +#endif
7461 diff -Nru linux/fs/udf/partition.c linux.new/fs/udf/partition.c
7462 --- linux/fs/udf/partition.c    Thu Jan  1 01:00:00 1970
7463 +++ linux.new/fs/udf/partition.c        Fri Sep  7 11:32:16 2001
7464 @@ -0,0 +1,233 @@
7465 +/*
7466 + * partition.c
7467 + *
7468 + * PURPOSE
7469 + *      Partition handling routines for the OSTA-UDF(tm) filesystem.
7470 + *
7471 + * CONTACTS
7472 + *      E-mail regarding any portion of the Linux UDF file system should be
7473 + *      directed to the development team mailing list (run by majordomo):
7474 + *              linux_udf@hootie.lvld.hp.com
7475 + *
7476 + * COPYRIGHT
7477 + *      This file is distributed under the terms of the GNU General Public
7478 + *      License (GPL). Copies of the GPL can be obtained from:
7479 + *              ftp://prep.ai.mit.edu/pub/gnu/GPL
7480 + *      Each contributing author retains all rights to their own work.
7481 + *
7482 + *  (C) 1998-2000 Ben Fennema
7483 + *
7484 + * HISTORY
7485 + *
7486 + * 12/06/98 blf  Created file. 
7487 + *
7488 + */
7489 +
7490 +#include "udfdecl.h"
7491 +#include "udf_sb.h"
7492 +#include "udf_i.h"
7493 +
7494 +#include <linux/fs.h>
7495 +#include <linux/string.h>
7496 +#include <linux/udf_fs.h>
7497 +#include <linux/malloc.h>
7498 +
7499 +inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
7500 +{
7501 +       if (partition >= UDF_SB_NUMPARTS(sb))
7502 +       {
7503 +               udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
7504 +                       block, partition, offset);
7505 +               return 0xFFFFFFFF;
7506 +       }
7507 +       if (UDF_SB_PARTFUNC(sb, partition))
7508 +               return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
7509 +       else
7510 +               return UDF_SB_PARTROOT(sb, partition) + block + offset;
7511 +}
7512 +
7513 +Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
7514 +{
7515 +       struct buffer_head *bh = NULL;
7516 +       Uint32 newblock;
7517 +       Uint32 index;
7518 +       Uint32 loc;
7519 +
7520 +       index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32);
7521 +
7522 +       if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
7523 +       {
7524 +               udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
7525 +                       block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
7526 +               return 0xFFFFFFFF;
7527 +       }
7528 +
7529 +       if (block >= index)
7530 +       {
7531 +               block -= index;
7532 +               newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32)));
7533 +               index = block % (sb->s_blocksize / sizeof(Uint32));
7534 +       }
7535 +       else
7536 +       {
7537 +               newblock = 0;
7538 +               index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
7539 +       }
7540 +
7541 +       loc = udf_bmap(UDF_SB_VAT(sb), newblock);
7542 +
7543 +       if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize)))
7544 +       {
7545 +               udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
7546 +                       sb, block, partition, loc, index);
7547 +               return 0xFFFFFFFF;
7548 +       }
7549 +
7550 +       loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]);
7551 +
7552 +       udf_release_data(bh);
7553 +
7554 +       if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
7555 +       {
7556 +               udf_debug("recursive call to udf_get_pblock!\n");
7557 +               return 0xFFFFFFFF;
7558 +       }
7559 +
7560 +       return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
7561 +}
7562 +
7563 +inline Uint32 udf_get_pblock_virt20(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
7564 +{
7565 +       return udf_get_pblock_virt15(sb, block, partition, offset);
7566 +}
7567 +
7568 +Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
7569 +{
7570 +       Uint32 packet = (block + offset) >> UDF_SB_TYPESPAR(sb,partition).s_spar_pshift;
7571 +       Uint32 index = 0;
7572 +
7573 +       if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 8)
7574 +               index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap8[packet];
7575 +       else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 16)
7576 +               index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap16[packet];
7577 +       else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 32)
7578 +               index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap32[packet];
7579 +
7580 +       if (index == ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize)-1))
7581 +               return UDF_SB_PARTROOT(sb,partition) + block + offset;
7582 +
7583 +       packet = UDF_SB_TYPESPAR(sb,partition).s_spar_map[index];
7584 +       return packet + ((block + offset) & ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_pshift)-1));
7585 +}
7586 +
7587 +void udf_fill_spartable(struct super_block *sb, struct udf_sparing_data *sdata, int partlen)
7588 +{
7589 +       Uint16 ident;
7590 +       Uint32 spartable;
7591 +       int i;
7592 +       struct buffer_head *bh;
7593 +       struct SparingTable *st;
7594 +
7595 +       for (i=0; i<4; i++)
7596 +       {
7597 +               if (!(spartable = sdata->s_spar_loc[i]))
7598 +                       continue;
7599 +
7600 +               bh = udf_read_tagged(sb, spartable, spartable, &ident);
7601 +
7602 +               if (!bh)
7603 +               {
7604 +                       sdata->s_spar_loc[i] = 0;
7605 +                       continue;
7606 +               }
7607 +
7608 +               if (ident == 0)
7609 +               {
7610 +                       st = (struct SparingTable *)bh->b_data;
7611 +                       if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
7612 +                       {
7613 +                               SparingEntry *se;
7614 +                               Uint16 rtl = le16_to_cpu(st->reallocationTableLen);
7615 +                               int index;
7616 +
7617 +                               if (!sdata->s_spar_map)
7618 +                               {
7619 +                                       int num = 1, mapsize;
7620 +                                       sdata->s_spar_indexsize = 8;
7621 +                                       while (rtl*sizeof(Uint32) >= (1 << sdata->s_spar_indexsize))
7622 +                                       {
7623 +                                               num ++;
7624 +                                               sdata->s_spar_indexsize <<= 1;
7625 +                                       }
7626 +                                       mapsize = (rtl * sizeof(Uint32)) +
7627 +                                               ((partlen/(1 << sdata->s_spar_pshift)) * sizeof(Uint8) * num);
7628 +                                       sdata->s_spar_map = kmalloc(mapsize, GFP_KERNEL);
7629 +                                       sdata->s_spar_remap.s_spar_remap32 = &sdata->s_spar_map[rtl];
7630 +                                       memset(sdata->s_spar_map, 0xFF, mapsize);
7631 +                               }
7632 +
7633 +                               index = sizeof(struct SparingTable);
7634 +                               for (i=0; i<rtl; i++)
7635 +                               {
7636 +                                       if (index > sb->s_blocksize)
7637 +                                       {
7638 +                                               udf_release_data(bh);
7639 +                                               bh = udf_tread(sb, ++spartable, sb->s_blocksize);
7640 +                                               if (!bh)
7641 +                                               {
7642 +                                                       sdata->s_spar_loc[i] = 0;
7643 +                                                       continue;
7644 +                                               }
7645 +                                               index = 0;
7646 +                                       }
7647 +                                       se = (SparingEntry *)&(bh->b_data[index]);
7648 +                                       index += sizeof(SparingEntry);
7649 +
7650 +                                       if (sdata->s_spar_map[i] == 0xFFFFFFFF)
7651 +                                               sdata->s_spar_map[i] = le32_to_cpu(se->mappedLocation);
7652 +                                       else if (sdata->s_spar_map[i] != le32_to_cpu(se->mappedLocation))
7653 +                                       {
7654 +                                               udf_debug("Found conflicting Sparing Data (%d vs %d for entry %d)\n",
7655 +                                                       sdata->s_spar_map[i], le32_to_cpu(se->mappedLocation), i);
7656 +                                       }
7657 +
7658 +                                       if (le32_to_cpu(se->origLocation) < 0xFFFFFFF0)
7659 +                                       {
7660 +                                               int packet = le32_to_cpu(se->origLocation) >> sdata->s_spar_pshift;
7661 +                                               if (sdata->s_spar_indexsize == 8)
7662 +                                               {
7663 +                                                       if (sdata->s_spar_remap.s_spar_remap8[packet] == 0xFF)
7664 +                                                               sdata->s_spar_remap.s_spar_remap8[packet] = i;
7665 +                                                       else if (sdata->s_spar_remap.s_spar_remap8[packet] != i)
7666 +                                                       {
7667 +                                                               udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
7668 +                                                                       sdata->s_spar_remap.s_spar_remap8[packet], i);
7669 +                                                       }
7670 +                                               }
7671 +                                               else if (sdata->s_spar_indexsize == 16)
7672 +                                               {
7673 +                                                       if (sdata->s_spar_remap.s_spar_remap16[packet] == 0xFFFF)
7674 +                                                               sdata->s_spar_remap.s_spar_remap16[packet] = i;
7675 +                                                       else if (sdata->s_spar_remap.s_spar_remap16[packet] != i)
7676 +                                                       {
7677 +                                                               udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
7678 +                                                                       sdata->s_spar_remap.s_spar_remap16[packet], i);
7679 +                                                       }
7680 +                                               }
7681 +                                               else if (sdata->s_spar_indexsize == 32)
7682 +                                               {
7683 +                                                       if (sdata->s_spar_remap.s_spar_remap32[packet] == 0xFFFFFFFF)
7684 +                                                               sdata->s_spar_remap.s_spar_remap32[packet] = i;
7685 +                                                       else if (sdata->s_spar_remap.s_spar_remap32[packet] != i)
7686 +                                                       {
7687 +                                                               udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
7688 +                                                                       sdata->s_spar_remap.s_spar_remap32[packet], i);
7689 +                                                       }
7690 +                                               }
7691 +                                       }
7692 +                               }
7693 +                       }
7694 +               }
7695 +               udf_release_data(bh);
7696 +       }
7697 +}
7698 diff -Nru linux/fs/udf/super.c linux.new/fs/udf/super.c
7699 --- linux/fs/udf/super.c        Thu Jan  1 01:00:00 1970
7700 +++ linux.new/fs/udf/super.c    Fri Sep  7 11:32:16 2001
7701 @@ -0,0 +1,1765 @@
7702 +/*
7703 + * super.c
7704 + *
7705 + * PURPOSE
7706 + *  Super block routines for the OSTA-UDF(tm) filesystem.
7707 + *
7708 + * DESCRIPTION
7709 + *  OSTA-UDF(tm) = Optical Storage Technology Association
7710 + *  Universal Disk Format.
7711 + *
7712 + *  This code is based on version 2.00 of the UDF specification,
7713 + *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
7714 + *    http://www.osta.org/
7715 + *    http://www.ecma.ch/
7716 + *    http://www.iso.org/
7717 + *
7718 + * CONTACTS
7719 + *  E-mail regarding any portion of the Linux UDF file system should be
7720 + *  directed to the development team mailing list (run by majordomo):
7721 + *       linux_udf@hootie.lvld.hp.com
7722 + *
7723 + * COPYRIGHT
7724 + *  This file is distributed under the terms of the GNU General Public
7725 + *  License (GPL). Copies of the GPL can be obtained from:
7726 + *    ftp://prep.ai.mit.edu/pub/gnu/GPL
7727 + *  Each contributing author retains all rights to their own work.
7728 + *
7729 + *  (C) 1998 Dave Boynton
7730 + *  (C) 1998-2000 Ben Fennema
7731 + *  (C) 2000 Stelias Computing Inc
7732 + *
7733 + * HISTORY
7734 + *
7735 + *  09/24/98 dgb  changed to allow compiling outside of kernel, and
7736 + *                added some debugging.
7737 + *  10/01/98 dgb  updated to allow (some) possibility of compiling w/2.0.34
7738 + *  10/16/98      attempting some multi-session support
7739 + *  10/17/98      added freespace count for "df"
7740 + *  11/11/98 gr   added novrs option
7741 + *  11/26/98 dgb  added fileset,anchor mount options
7742 + *  12/06/98 blf  really hosed things royally. vat/sparing support. sequenced vol descs
7743 + *                rewrote option handling based on isofs
7744 + *  12/20/98      find the free space bitmap (if it exists)
7745 + */
7746 +
7747 +#include "udfdecl.h"    
7748 +
7749 +#include <linux/config.h>
7750 +#include <linux/version.h>
7751 +#include <linux/blkdev.h>
7752 +#include <linux/malloc.h>
7753 +#include <linux/kernel.h>
7754 +#include <linux/locks.h>
7755 +#include <linux/module.h>
7756 +#include <linux/stat.h>
7757 +#include <linux/cdrom.h>
7758 +#include <linux/nls.h>
7759 +#include <asm/byteorder.h>
7760 +
7761 +#include <linux/udf_fs.h>
7762 +#include "udf_sb.h"
7763 +#include "udf_i.h"
7764 +
7765 +#include <linux/init.h>
7766 +#include <asm/uaccess.h>
7767 +
7768 +#define VDS_POS_PRIMARY_VOL_DESC       0
7769 +#define VDS_POS_UNALLOC_SPACE_DESC     1
7770 +#define VDS_POS_LOGICAL_VOL_DESC       2
7771 +#define VDS_POS_PARTITION_DESC         3
7772 +#define VDS_POS_IMP_USE_VOL_DESC       4
7773 +#define VDS_POS_VOL_DESC_PTR           5
7774 +#define VDS_POS_TERMINATING_DESC       6
7775 +#define VDS_POS_LENGTH                         7
7776 +
7777 +static char error_buf[1024];
7778 +
7779 +/* These are the "meat" - everything else is stuffing */
7780 +static struct super_block *udf_read_super(struct super_block *, void *, int);
7781 +static void udf_put_super(struct super_block *);
7782 +static void udf_write_super(struct super_block *);
7783 +static int udf_remount_fs(struct super_block *, int *, char *);
7784 +static int udf_check_valid(struct super_block *, int, int);
7785 +static int udf_vrs(struct super_block *sb, int silent);
7786 +static int udf_load_partition(struct super_block *, lb_addr *);
7787 +static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
7788 +static void udf_load_logicalvolint(struct super_block *, extent_ad);
7789 +static int udf_find_anchor(struct super_block *, int, int);
7790 +static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
7791 +static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
7792 +static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
7793 +static void udf_load_partdesc(struct super_block *, struct buffer_head *);
7794 +static void udf_open_lvid(struct super_block *);
7795 +static void udf_close_lvid(struct super_block *);
7796 +static unsigned int udf_count_free(struct super_block *);
7797 +static int udf_statfs(struct super_block *, struct statfs *, int);
7798 +
7799 +/* UDF filesystem type */
7800 +static struct file_system_type udf_fstype = {
7801 +       "udf",                          /* name */
7802 +       FS_REQUIRES_DEV,        /* fs_flags */
7803 +       udf_read_super,         /* read_super */
7804 +       NULL                            /* next */
7805 +};
7806 +
7807 +/* Superblock operations */
7808 +static struct super_operations udf_sb_ops =
7809 +{
7810 +       udf_read_inode,         /* read_inode */
7811 +       udf_write_inode,        /* write_inode */
7812 +       udf_put_inode,          /* put_inode */
7813 +       udf_delete_inode,       /* delete_inode */
7814 +       NULL,                           /* notify_change */
7815 +       udf_put_super,          /* put_super */
7816 +       udf_write_super,        /* write_super */
7817 +       udf_statfs,                     /* statfs */
7818 +       udf_remount_fs,         /* remount_fs */
7819 +       NULL,                           /* clear_inode */
7820 +       NULL,                           /* umount_begin */
7821 +};
7822 +
7823 +struct udf_options
7824 +{
7825 +       unsigned char novrs;
7826 +       unsigned int blocksize;
7827 +       unsigned int session;
7828 +       unsigned int lastblock;
7829 +       unsigned int anchor;
7830 +       unsigned int volume;
7831 +       unsigned short partition;
7832 +       unsigned int fileset;
7833 +       unsigned int rootdir;
7834 +       unsigned int flags;
7835 +       mode_t umask;
7836 +       gid_t gid;
7837 +       uid_t uid;
7838 +};
7839 +
7840 +#if defined(MODULE)
7841 +       
7842 +/*
7843 + * cleanup_module
7844 + *
7845 + * PURPOSE
7846 + *     Unregister the UDF filesystem type.
7847 + *
7848 + * DESCRIPTION
7849 + *     Clean-up before the module is unloaded.
7850 + *     This routine only applies when compiled as a module.
7851 + *
7852 + * HISTORY
7853 + *     July 1, 1997 - Andrew E. Mileski
7854 + *     Written, tested, and released.
7855 + */
7856 +int
7857 +cleanup_module(void)
7858 +{
7859 +       printk(KERN_NOTICE "udf: unregistering filesystem\n");
7860 +       return unregister_filesystem(&udf_fstype);
7861 +}
7862 +
7863 +/*
7864 + * init_module / init_udf_fs
7865 + *
7866 + * PURPOSE
7867 + *     Register the UDF filesystem type.
7868 + *
7869 + * HISTORY
7870 + *     July 1, 1997 - Andrew E. Mileski
7871 + *     Written, tested, and released.
7872 + */
7873 +int init_module(void)
7874 +#else /* if !defined(MODULE) */
7875 +__initfunc(int init_udf_fs(void))
7876 +#endif
7877 +{
7878 +       printk(KERN_NOTICE "udf: registering filesystem\n");
7879 +       {
7880 +               struct super_block sb;
7881 +               int size;
7882 +
7883 +               size = sizeof(struct super_block) +
7884 +                       (long)&sb.u - (long)&sb;
7885 +               if ( size < sizeof(struct udf_sb_info) )
7886 +               {
7887 +                       printk(KERN_ERR "udf: Danger! Kernel was compiled without enough room for udf_sb_info\n");
7888 +                       printk(KERN_ERR "udf: Kernel has room for %u bytes, udf needs %lu\n",
7889 +                               size, (unsigned long)sizeof(struct udf_sb_info));
7890 +                       return 0;
7891 +               }
7892 +       }
7893 +       return register_filesystem(&udf_fstype);
7894 +}
7895 +
7896 +/*
7897 + * udf_parse_options
7898 + *
7899 + * PURPOSE
7900 + *     Parse mount options.
7901 + *
7902 + * DESCRIPTION
7903 + *     The following mount options are supported:
7904 + *
7905 + *     gid=            Set the default group.
7906 + *     umask=          Set the default umask.
7907 + *     uid=            Set the default user.
7908 + *     bs=                     Set the block size.
7909 + *     unhide          Show otherwise hidden files.
7910 + *     undelete        Show deleted files in lists.
7911 + *     adinicb         Embed data in the inode (default)
7912 + *     noadinicb       Don't embed data in the inode
7913 + *     shortad         Use short ad's
7914 + *     longad          Use long ad's (default)
7915 + *     strict          Set strict conformance (unused)
7916 + *
7917 + *     The remaining are for debugging and disaster recovery:
7918 + *
7919 + *     novrs           Skip volume sequence recognition 
7920 + *
7921 + *     The following expect a offset from 0.
7922 + *
7923 + *     session=        Set the CDROM session (default= last session)
7924 + *     anchor=         Override standard anchor location. (default= 256)
7925 + *     volume=         Override the VolumeDesc location. (unused)
7926 + *     partition=      Override the PartitionDesc location. (unused)
7927 + *     lastblock=      Set the last block of the filesystem/
7928 + *
7929 + *     The following expect a offset from the partition root.
7930 + *
7931 + *     fileset=        Override the fileset block location. (unused)
7932 + *     rootdir=        Override the root directory location. (unused)
7933 + *             WARNING: overriding the rootdir to a non-directory may
7934 + *             yield highly unpredictable results.
7935 + *
7936 + * PRE-CONDITIONS
7937 + *     options         Pointer to mount options string.
7938 + *     uopts           Pointer to mount options variable.
7939 + *
7940 + * POST-CONDITIONS
7941 + *     <return>        0       Mount options parsed okay.
7942 + *     <return>        -1      Error parsing mount options.
7943 + *
7944 + * HISTORY
7945 + *     July 1, 1997 - Andrew E. Mileski
7946 + *     Written, tested, and released.
7947 + */
7948 +
7949 +static int
7950 +udf_parse_options(char *options, struct udf_options *uopt)
7951 +{
7952 +       char *opt, *val;
7953 +
7954 +       uopt->novrs = 0;
7955 +       uopt->blocksize = 512;
7956 +       uopt->partition = 0xFFFF;
7957 +       uopt->session = 0xFFFFFFFF;
7958 +       uopt->lastblock = 0xFFFFFFFF;
7959 +       uopt->anchor = 0xFFFFFFFF;
7960 +       uopt->volume = 0xFFFFFFFF;
7961 +       uopt->rootdir = 0xFFFFFFFF;
7962 +       uopt->fileset = 0xFFFFFFFF;
7963 +
7964 +       if (!options)
7965 +               return 1;
7966 +
7967 +       for (opt = strtok(options, ","); opt; opt = strtok(NULL, ","))
7968 +       {
7969 +               /* Make "opt=val" into two strings */
7970 +               val = strchr(opt, '=');
7971 +               if (val)
7972 +                       *(val++) = 0;
7973 +               if (!strcmp(opt, "novrs") && !val)
7974 +                       uopt->novrs = 1;
7975 +               else if (!strcmp(opt, "bs") && val)
7976 +                       uopt->blocksize = simple_strtoul(val, NULL, 0);
7977 +               else if (!strcmp(opt, "unhide") && !val)
7978 +                       uopt->flags |= (1 << UDF_FLAG_UNHIDE);
7979 +               else if (!strcmp(opt, "undelete") && !val)
7980 +                       uopt->flags |= (1 << UDF_FLAG_UNDELETE);
7981 +               else if (!strcmp(opt, "noadinicb") && !val)
7982 +                       uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
7983 +               else if (!strcmp(opt, "adinicb") && !val)
7984 +                       uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
7985 +               else if (!strcmp(opt, "shortad") && !val)
7986 +                       uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
7987 +               else if (!strcmp(opt, "longad") && !val)
7988 +                       uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
7989 +               else if (!strcmp(opt, "gid") && val)
7990 +                       uopt->gid = simple_strtoul(val, NULL, 0);
7991 +               else if (!strcmp(opt, "umask") && val)
7992 +                       uopt->umask = simple_strtoul(val, NULL, 0);
7993 +               else if (!strcmp(opt, "strict") && !val)
7994 +                       uopt->flags |= (1 << UDF_FLAG_STRICT);
7995 +               else if (!strcmp(opt, "uid") && val)
7996 +                       uopt->uid = simple_strtoul(val, NULL, 0);
7997 +               else if (!strcmp(opt, "session") && val)
7998 +                       uopt->session = simple_strtoul(val, NULL, 0);
7999 +               else if (!strcmp(opt, "lastblock") && val)
8000 +                       uopt->lastblock = simple_strtoul(val, NULL, 0);
8001 +               else if (!strcmp(opt, "anchor") && val)
8002 +                       uopt->anchor = simple_strtoul(val, NULL, 0);
8003 +               else if (!strcmp(opt, "volume") && val)
8004 +                       uopt->volume = simple_strtoul(val, NULL, 0);
8005 +               else if (!strcmp(opt, "partition") && val)
8006 +                       uopt->partition = simple_strtoul(val, NULL, 0);
8007 +               else if (!strcmp(opt, "fileset") && val)
8008 +                       uopt->fileset = simple_strtoul(val, NULL, 0);
8009 +               else if (!strcmp(opt, "rootdir") && val)
8010 +                       uopt->rootdir = simple_strtoul(val, NULL, 0);
8011 +               else if (val)
8012 +               {
8013 +                       printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
8014 +                               opt, val);
8015 +                       return 0;
8016 +               }
8017 +               else
8018 +               {
8019 +                       printk(KERN_ERR "udf: bad mount option \"%s\"\n",
8020 +                               opt);
8021 +                       return 0;
8022 +               }
8023 +       }
8024 +       return 1;
8025 +}
8026 +
8027 +void
8028 +udf_write_super(struct super_block *sb)
8029 +{
8030 +       if (!(sb->s_flags & MS_RDONLY))
8031 +               udf_open_lvid(sb);
8032 +       sb->s_dirt = 0;
8033 +}
8034 +
8035 +static int
8036 +udf_remount_fs(struct super_block *sb, int *flags, char *options)
8037 +{
8038 +       struct udf_options uopt;
8039 +
8040 +       uopt.flags = UDF_SB(sb)->s_flags ;
8041 +       uopt.uid   = UDF_SB(sb)->s_uid ;
8042 +       uopt.gid   = UDF_SB(sb)->s_gid ;
8043 +       uopt.umask = UDF_SB(sb)->s_umask ;
8044 +
8045 +       if ( !udf_parse_options(options, &uopt) )
8046 +               return -EINVAL;
8047 +
8048 +       UDF_SB(sb)->s_flags = uopt.flags;
8049 +       UDF_SB(sb)->s_uid   = uopt.uid;
8050 +       UDF_SB(sb)->s_gid   = uopt.gid;
8051 +       UDF_SB(sb)->s_umask = uopt.umask;
8052 +
8053 +#if CONFIG_UDF_RW != 1
8054 +       *flags |= MS_RDONLY;
8055 +#endif
8056 +
8057 +       if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
8058 +               return 0;
8059 +       if (*flags & MS_RDONLY)
8060 +               udf_close_lvid(sb);
8061 +       else
8062 +               udf_open_lvid(sb);
8063 +
8064 +       return 0;
8065 +}
8066 +
8067 +/*
8068 + * udf_set_blocksize
8069 + *
8070 + * PURPOSE
8071 + *     Set the block size to be used in all transfers.
8072 + *
8073 + * DESCRIPTION
8074 + *     To allow room for a DMA transfer, it is best to guess big when unsure.
8075 + *     This routine picks 2048 bytes as the blocksize when guessing. This
8076 + *     should be adequate until devices with larger block sizes become common.
8077 + *
8078 + *     Note that the Linux kernel can currently only deal with blocksizes of
8079 + *     512, 1024, 2048, 4096, and 8192 bytes.
8080 + *
8081 + * PRE-CONDITIONS
8082 + *     sb                      Pointer to _locked_ superblock.
8083 + *
8084 + * POST-CONDITIONS
8085 + *     sb->s_blocksize         Blocksize.
8086 + *     sb->s_blocksize_bits    log2 of blocksize.
8087 + *     <return>        0       Blocksize is valid.
8088 + *     <return>        1       Blocksize is invalid.
8089 + *
8090 + * HISTORY
8091 + *     July 1, 1997 - Andrew E. Mileski
8092 + *     Written, tested, and released.
8093 + */
8094 +static  int
8095 +udf_set_blocksize(struct super_block *sb, int bsize)
8096 +{
8097 +       /* Use specified block size if specified */
8098 +       if (!(sb->s_blocksize = get_hardblocksize(sb->s_dev)))
8099 +               sb->s_blocksize = 2048;
8100 +       if (bsize > sb->s_blocksize)
8101 +               sb->s_blocksize = bsize;
8102 +
8103 +       /* Block size must be an even multiple of 512 */
8104 +       switch (sb->s_blocksize) {
8105 +               case 512: sb->s_blocksize_bits = 9;     break;
8106 +               case 1024: sb->s_blocksize_bits = 10; break;
8107 +               case 2048: sb->s_blocksize_bits = 11; break;
8108 +               case 4096: sb->s_blocksize_bits = 12; break;
8109 +               case 8192: sb->s_blocksize_bits = 13; break;
8110 +               default:
8111 +               {
8112 +                       udf_debug("Bad block size (%ld)\n", sb->s_blocksize);
8113 +                       printk(KERN_ERR "udf: bad block size (%ld)\n", sb->s_blocksize);
8114 +                       return 0;
8115 +               }
8116 +       }
8117 +
8118 +       /* Set the block size */
8119 +       set_blocksize(sb->s_dev, sb->s_blocksize);
8120 +       return sb->s_blocksize;
8121 +}
8122 +
8123 +static int
8124 +udf_vrs(struct super_block *sb, int silent)
8125 +{
8126 +       struct VolStructDesc *vsd = NULL;
8127 +       int sector = 32768;
8128 +       struct buffer_head *bh = NULL;
8129 +       int iso9660=0;
8130 +       int nsr02=0;
8131 +       int nsr03=0;
8132 +
8133 +       /* Block size must be a multiple of 512 */
8134 +       if (sb->s_blocksize & 511)
8135 +               return sector;
8136 +
8137 +       sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
8138 +
8139 +       udf_debug("Starting at sector %u (%ld byte sectors)\n",
8140 +               (sector >> sb->s_blocksize_bits), sb->s_blocksize);
8141 +       /* Process the sequence (if applicable) */
8142 +       for (;!nsr02 && !nsr03; sector += 2048)
8143 +       {
8144 +               /* Read a block */
8145 +               bh = udf_tread(sb, sector >> sb->s_blocksize_bits, sb->s_blocksize);
8146 +               if (!bh)
8147 +                       break;
8148 +
8149 +               /* Look for ISO  descriptors */
8150 +               vsd = (struct VolStructDesc *)(bh->b_data +
8151 +                       (sector & (sb->s_blocksize - 1)));
8152 +
8153 +               if (vsd->stdIdent[0] == 0)
8154 +               {
8155 +                       udf_release_data(bh);
8156 +                       break;
8157 +               }
8158 +               else if (!strncmp(vsd->stdIdent, STD_ID_CD001, STD_ID_LEN))
8159 +               {
8160 +                       iso9660 = sector;
8161 +                       switch (vsd->structType)
8162 +                       {
8163 +                               case 0: 
8164 +                                       udf_debug("ISO9660 Boot Record found\n");
8165 +                                       break;
8166 +                               case 1: 
8167 +                                       udf_debug("ISO9660 Primary Volume Descriptor found\n");
8168 +                                       break;
8169 +                               case 2: 
8170 +                                       udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
8171 +                                       break;
8172 +                               case 3: 
8173 +                                       udf_debug("ISO9660 Volume Partition Descriptor found\n");
8174 +                                       break;
8175 +                               case 255: 
8176 +                                       udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
8177 +                                       break;
8178 +                               default: 
8179 +                                       udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
8180 +                                       break;
8181 +                       }
8182 +               }
8183 +               else if (!strncmp(vsd->stdIdent, STD_ID_BEA01, STD_ID_LEN))
8184 +               {
8185 +               }
8186 +               else if (!strncmp(vsd->stdIdent, STD_ID_TEA01, STD_ID_LEN))
8187 +               {
8188 +                       udf_release_data(bh);
8189 +                       break;
8190 +               }
8191 +               else if (!strncmp(vsd->stdIdent, STD_ID_NSR02, STD_ID_LEN))
8192 +               {
8193 +                       nsr02 = sector;
8194 +               }
8195 +               else if (!strncmp(vsd->stdIdent, STD_ID_NSR03, STD_ID_LEN))
8196 +               {
8197 +                       nsr03 = sector;
8198 +               }
8199 +               udf_release_data(bh);
8200 +       }
8201 +
8202 +       if (nsr03)
8203 +               return nsr03;
8204 +       else if (nsr02)
8205 +               return nsr02;
8206 +       else if (sector - (UDF_SB_SESSION(sb) << sb->s_blocksize_bits) == 32768)
8207 +               return -1;
8208 +       else
8209 +               return 0;
8210 +}
8211 +
8212 +/*
8213 + * udf_find_anchor
8214 + *
8215 + * PURPOSE
8216 + *     Find an anchor volume descriptor.
8217 + *
8218 + * PRE-CONDITIONS
8219 + *     sb                      Pointer to _locked_ superblock.
8220 + *     lastblock               Last block on media.
8221 + *
8222 + * POST-CONDITIONS
8223 + *     <return>                1 if not found, 0 if ok
8224 + *
8225 + * HISTORY
8226 + *     July 1, 1997 - Andrew E. Mileski
8227 + *     Written, tested, and released.
8228 + */
8229 +static int
8230 +udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
8231 +{
8232 +       int varlastblock = udf_variable_to_fixed(lastblock);
8233 +       int last[] =  { lastblock, lastblock - 2,
8234 +                                       lastblock - 150, lastblock - 152,
8235 +                                       varlastblock, varlastblock - 2,
8236 +                                       varlastblock - 150, varlastblock - 152 };
8237 +       struct buffer_head *bh = NULL;
8238 +       Uint16 ident;
8239 +       Uint32 location;
8240 +       int i;
8241 +
8242 +       UDF_SB_ANCHOR(sb)[0] = 0;
8243 +       UDF_SB_ANCHOR(sb)[1] = 0;
8244 +       UDF_SB_ANCHOR(sb)[2] = 0;
8245 +       UDF_SB_ANCHOR(sb)[3] = 256 + UDF_SB_SESSION(sb);
8246 +
8247 +       lastblock = 0;
8248 +
8249 +       /* Search for an anchor volume descriptor pointer */
8250 +
8251 +       /*  according to spec, anchor is in either:
8252 +        *     block 256
8253 +        *     lastblock-256
8254 +        *     lastblock
8255 +        *  however, if the disc isn't closed, it could be 512 */
8256 +
8257 +       for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
8258 +       {
8259 +               if (!(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
8260 +               {
8261 +                       ident = location = 0;
8262 +               }
8263 +               else
8264 +               {
8265 +                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
8266 +                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
8267 +                       udf_release_data(bh);
8268 +               }
8269 +
8270 +               if (ident == TID_ANCHOR_VOL_DESC_PTR)
8271 +               {
8272 +                       if (location == last[i] - UDF_SB_SESSION(sb))
8273 +                       {
8274 +                               lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
8275 +                               UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
8276 +                       }
8277 +                       else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
8278 +                       {
8279 +                               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
8280 +                               lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
8281 +                               UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
8282 +                       }
8283 +                       else
8284 +                               udf_debug("Anchor found at block %d, location mismatch %d.\n",
8285 +                                       last[i], location);
8286 +               }
8287 +               else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
8288 +               {
8289 +                       lastblock = last[i];
8290 +                       UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb);
8291 +               }
8292 +               else
8293 +               {
8294 +                       if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
8295 +                       {
8296 +                               ident = location = 0;
8297 +                       }
8298 +                       else
8299 +                       {
8300 +                               ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
8301 +                               location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
8302 +                               udf_release_data(bh);
8303 +                       }
8304 +
8305 +                       if (ident == TID_ANCHOR_VOL_DESC_PTR &&
8306 +                               location == last[i] - 256 - UDF_SB_SESSION(sb))
8307 +                       {
8308 +                               lastblock = last[i];
8309 +                               UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
8310 +                       }
8311 +                       else
8312 +                       {
8313 +                               if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
8314 +                                       sb->s_blocksize)))
8315 +                               {
8316 +                                       ident = location = 0;
8317 +                               }
8318 +                               else
8319 +                               {
8320 +                                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
8321 +                                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
8322 +                                       udf_release_data(bh);
8323 +                               }
8324 +
8325 +                               if (ident == TID_ANCHOR_VOL_DESC_PTR &&
8326 +                                       location == udf_variable_to_fixed(last[i]) - 256)
8327 +                               {
8328 +                                       UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
8329 +                                       lastblock = udf_variable_to_fixed(last[i]);
8330 +                                       UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
8331 +                               }
8332 +                       }
8333 +               }
8334 +       }
8335 +
8336 +       if (!lastblock)
8337 +       {
8338 +               /* We havn't found the lastblock. check 312 */
8339 +               if ((bh = bread(sb->s_dev, 312 + UDF_SB_SESSION(sb), sb->s_blocksize)))
8340 +               {
8341 +                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
8342 +                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
8343 +                       udf_release_data(bh);
8344 +
8345 +                       if (ident == TID_ANCHOR_VOL_DESC_PTR && location == 256)
8346 +                               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
8347 +               }
8348 +       }
8349 +
8350 +       for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
8351 +       {
8352 +               if (UDF_SB_ANCHOR(sb)[i])
8353 +               {
8354 +                       if (!(bh = udf_read_tagged(sb,
8355 +                               UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
8356 +                       {
8357 +                               UDF_SB_ANCHOR(sb)[i] = 0;
8358 +                       }
8359 +                       else
8360 +                       {
8361 +                               udf_release_data(bh);
8362 +                               if ((ident != TID_ANCHOR_VOL_DESC_PTR) && (i ||
8363 +                                       (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY)))
8364 +                               {
8365 +                                       UDF_SB_ANCHOR(sb)[i] = 0;
8366 +                               }
8367 +                       }
8368 +               }
8369 +               else if (useranchor != 0xFFFFFFFF)
8370 +               {
8371 +                       UDF_SB_ANCHOR(sb)[i] = useranchor;
8372 +                       useranchor = 0xFFFFFFFF;
8373 +                       i --;
8374 +               }
8375 +       }
8376 +
8377 +       return lastblock;
8378 +}
8379 +
8380 +static int 
8381 +udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
8382 +{
8383 +       struct buffer_head *bh = NULL;
8384 +       long lastblock;
8385 +       Uint16 ident;
8386 +
8387 +       if (fileset->logicalBlockNum != 0xFFFFFFFF ||
8388 +               fileset->partitionReferenceNum != 0xFFFF)
8389 +       {
8390 +               bh = udf_read_ptagged(sb, *fileset, 0, &ident);
8391 +
8392 +               if (!bh)
8393 +                       return 1;
8394 +               else if (ident != TID_FILE_SET_DESC)
8395 +               {
8396 +                       udf_release_data(bh);
8397 +                       return 1;
8398 +               }
8399 +                       
8400 +       }
8401 +
8402 +       if (!bh) /* Search backwards through the partitions */
8403 +       {
8404 +               lb_addr newfileset;
8405 +
8406 +               return 1;
8407 +               
8408 +               for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1;
8409 +                       (newfileset.partitionReferenceNum != 0xFFFF &&
8410 +                               fileset->logicalBlockNum == 0xFFFFFFFF &&
8411 +                               fileset->partitionReferenceNum == 0xFFFF);
8412 +                       newfileset.partitionReferenceNum--)
8413 +               {
8414 +                       lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
8415 +                       newfileset.logicalBlockNum = 0;
8416 +
8417 +                       do
8418 +                       {
8419 +                               bh = udf_read_ptagged(sb, newfileset, 0, &ident);
8420 +                               if (!bh)
8421 +                               {
8422 +                                       newfileset.logicalBlockNum ++;
8423 +                                       continue;
8424 +                               }
8425 +
8426 +                               switch (ident)
8427 +                               {
8428 +                                       case TID_SPACE_BITMAP_DESC:
8429 +                                       {
8430 +                                               struct SpaceBitmapDesc *sp;
8431 +                                               sp = (struct SpaceBitmapDesc *)bh->b_data;
8432 +                                               newfileset.logicalBlockNum += 1 +
8433 +                                                       ((le32_to_cpu(sp->numOfBytes) + sizeof(struct SpaceBitmapDesc) - 1)
8434 +                                                               >> sb->s_blocksize_bits);
8435 +                                               udf_release_data(bh);
8436 +                                               break;
8437 +                                       }
8438 +                                       case TID_FILE_SET_DESC:
8439 +                                       {
8440 +                                               *fileset = newfileset;
8441 +                                               break;
8442 +                                       }
8443 +                                       default:
8444 +                                       {
8445 +                                               newfileset.logicalBlockNum ++;
8446 +                                               udf_release_data(bh);
8447 +                                               bh = NULL;
8448 +                                               break;
8449 +                                       }
8450 +                               }
8451 +                       }
8452 +                       while (newfileset.logicalBlockNum < lastblock &&
8453 +                               fileset->logicalBlockNum == 0xFFFFFFFF &&
8454 +                               fileset->partitionReferenceNum == 0xFFFF);
8455 +               }
8456 +       }
8457 +
8458 +       if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
8459 +               fileset->partitionReferenceNum != 0xFFFF) && bh)
8460 +       {
8461 +               udf_debug("Fileset at block=%d, partition=%d\n",
8462 +                       fileset->logicalBlockNum, fileset->partitionReferenceNum);
8463 +
8464 +               UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
8465 +               udf_load_fileset(sb, bh, root);
8466 +               udf_release_data(bh);
8467 +               return 0;
8468 +       }
8469 +       return 1;
8470 +}
8471 +
8472 +static void 
8473 +udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
8474 +{
8475 +       struct PrimaryVolDesc *pvoldesc;
8476 +       time_t recording;
8477 +       long recording_usec;
8478 +       struct ustr instr;
8479 +       struct ustr outstr;
8480 +
8481 +       pvoldesc = (struct PrimaryVolDesc *)bh->b_data;
8482 +
8483 +       if ( udf_stamp_to_time(&recording, &recording_usec,
8484 +               lets_to_cpu(pvoldesc->recordingDateAndTime)) )
8485 +       {
8486 +               timestamp ts;
8487 +               ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
8488 +               udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
8489 +                       recording, recording_usec,
8490 +                       ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
8491 +               UDF_SB_RECORDTIME(sb) = recording;
8492 +       }
8493 +
8494 +       if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) )
8495 +       {
8496 +               if (udf_CS0toUTF8(&outstr, &instr))
8497 +               {
8498 +                       strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name,
8499 +                               outstr.u_len > 31 ? 31 : outstr.u_len);
8500 +                       udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));
8501 +               }
8502 +       }
8503 +
8504 +       if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) )
8505 +       {
8506 +               if (udf_CS0toUTF8(&outstr, &instr))
8507 +                       udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
8508 +       }
8509 +}
8510 +
8511 +static void 
8512 +udf_load_fileset(struct super_block *sb, struct buffer_head *bh, lb_addr *root)
8513 +{
8514 +       struct FileSetDesc *fset;
8515 +
8516 +       fset = (struct FileSetDesc *)bh->b_data;
8517 +
8518 +       *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
8519 +
8520 +       UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);
8521 +
8522 +       udf_debug("Rootdir at block=%d, partition=%d\n", 
8523 +               root->logicalBlockNum, root->partitionReferenceNum);
8524 +}
8525 +
8526 +static void 
8527 +udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
8528 +{
8529 +       struct PartitionDesc *p;
8530 +       int i;
8531 +
8532 +       p=(struct PartitionDesc *)bh->b_data;
8533 +
8534 +       for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
8535 +       {
8536 +               udf_debug("Searching map: (%d == %d)\n", 
8537 +                       UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));
8538 +               if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber))
8539 +               {
8540 +                       UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
8541 +                       UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb);
8542 +
8543 +                       if (UDF_SB_PARTTYPE(sb,i) == UDF_SPARABLE_MAP15)
8544 +                               udf_fill_spartable(sb, &UDF_SB_TYPESPAR(sb,i), UDF_SB_PARTLEN(sb,i));
8545 +
8546 +                       if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) ||
8547 +                               !strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03))
8548 +                       {
8549 +                               struct PartitionHeaderDesc *phd;
8550 +
8551 +                               phd = (struct PartitionHeaderDesc *)(p->partitionContentsUse);
8552 +                               if (phd->unallocatedSpaceTable.extLength)
8553 +                               {
8554 +                                       lb_addr loc = { i, phd->unallocatedSpaceTable.extPosition };
8555 +
8556 +                                       UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
8557 +                                               udf_iget(sb, loc);
8558 +                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
8559 +                                       udf_debug("unallocatedSpaceTable (part %d) @ %ld\n",
8560 +                                               i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
8561 +                               }
8562 +                               if (phd->unallocatedSpaceBitmap.extLength)
8563 +                               {
8564 +                                       UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
8565 +                                       UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
8566 +                                               le32_to_cpu(phd->unallocatedSpaceBitmap.extLength);
8567 +                                       UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
8568 +                                               le32_to_cpu(phd->unallocatedSpaceBitmap.extPosition);
8569 +                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
8570 +                                       udf_debug("unallocatedSpaceBitmap (part %d) @ %d\n",
8571 +                                               i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
8572 +                               }
8573 +                               if (phd->partitionIntegrityTable.extLength)
8574 +                                       udf_debug("partitionIntegrityTable (part %d)\n", i);
8575 +                               if (phd->freedSpaceTable.extLength)
8576 +                               {
8577 +                                       lb_addr loc = { i, phd->freedSpaceTable.extPosition };
8578 +
8579 +                                       UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
8580 +                                               udf_iget(sb, loc);
8581 +                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
8582 +                                       udf_debug("freedSpaceTable (part %d) @ %ld\n",
8583 +                                               i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
8584 +                               }
8585 +                               if (phd->freedSpaceBitmap.extLength)
8586 +                               {
8587 +                                       UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
8588 +                                       UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
8589 +                                               le32_to_cpu(phd->freedSpaceBitmap.extLength);
8590 +                                       UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
8591 +                                               le32_to_cpu(phd->freedSpaceBitmap.extPosition);
8592 +                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
8593 +                                       udf_debug("freedSpaceBitmap (part %d) @ %d\n",
8594 +                                               i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
8595 +                               }
8596 +                       }
8597 +                       break;
8598 +               }
8599 +       }
8600 +       if (i == UDF_SB_NUMPARTS(sb))
8601 +       {
8602 +               udf_debug("Partition (%d) not found in partition map\n", le16_to_cpu(p->partitionNumber));
8603 +       }
8604 +       else
8605 +       {
8606 +               udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
8607 +                       le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
8608 +                       UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
8609 +       }
8610 +}
8611 +
8612 +static int 
8613 +udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset)
8614 +{
8615 +       struct LogicalVolDesc *lvd;
8616 +       int i, j, offset;
8617 +       Uint8 type;
8618 +
8619 +       lvd = (struct LogicalVolDesc *)bh->b_data;
8620 +
8621 +       UDF_SB_NUMPARTS(sb) = le32_to_cpu(lvd->numPartitionMaps);
8622 +       UDF_SB_ALLOC_PARTMAPS(sb, UDF_SB_NUMPARTS(sb));
8623 +
8624 +       for (i=0,offset=0;
8625 +                i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
8626 +                i++,offset+=((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
8627 +       {
8628 +               type = ((struct GenericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
8629 +               if (type == 1)
8630 +               {
8631 +                       struct GenericPartitionMap1 *gpm1 = (struct GenericPartitionMap1 *)&(lvd->partitionMaps[offset]);
8632 +                       UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
8633 +                       UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
8634 +                       UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
8635 +                       UDF_SB_PARTFUNC(sb,i) = NULL;
8636 +               }
8637 +               else if (type == 2)
8638 +               {
8639 +                       struct UdfPartitionMap2 *upm2 = (struct UdfPartitionMap2 *)&(lvd->partitionMaps[offset]);
8640 +                       if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
8641 +                       {
8642 +                               if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
8643 +                               {
8644 +                                       UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
8645 +                                       UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
8646 +                               }
8647 +                               else if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
8648 +                               {
8649 +                                       UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
8650 +                                       UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
8651 +                               }
8652 +                       }
8653 +                       else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
8654 +                       {
8655 +                               int plen;
8656 +
8657 +                               struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]);
8658 +                               UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
8659 +                               plen = le16_to_cpu(spm->packetLength);
8660 +                               UDF_SB_TYPESPAR(sb,i).s_spar_pshift = 0;
8661 +                               while (plen >>= 1)
8662 +                                       UDF_SB_TYPESPAR(sb,i).s_spar_pshift ++;
8663 +                               for (j=0; j<spm->numSparingTables; j++)
8664 +                                       UDF_SB_TYPESPAR(sb,i).s_spar_loc[j] = le32_to_cpu(spm->locSparingTable[j]);
8665 +                               UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
8666 +                       }
8667 +                       else
8668 +                       {
8669 +                               udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
8670 +                               continue;
8671 +                       }
8672 +                       UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
8673 +                       UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
8674 +               }
8675 +               udf_debug("Partition (%d:%d) type %d on volume %d\n",
8676 +                       i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
8677 +       }
8678 +
8679 +       if (fileset)
8680 +       {
8681 +               long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
8682 +
8683 +               *fileset = lelb_to_cpu(la->extLocation);
8684 +               udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
8685 +                       fileset->logicalBlockNum,
8686 +                       fileset->partitionReferenceNum);
8687 +       }
8688 +       if (lvd->integritySeqExt.extLength)
8689 +               udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
8690 +       return 0;
8691 +}
8692 +
8693 +/*
8694 + * udf_load_logicalvolint
8695 + *
8696 + */
8697 +static void
8698 +udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
8699 +{
8700 +       struct buffer_head *bh = NULL;
8701 +       Uint16 ident;
8702 +
8703 +       while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) &&
8704 +               ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0)
8705 +       {
8706 +               UDF_SB_LVIDBH(sb) = bh;
8707 +               
8708 +               if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
8709 +                       udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
8710 +               
8711 +               if (UDF_SB_LVIDBH(sb) != bh)
8712 +                       udf_release_data(bh);
8713 +               loc.extLength -= sb->s_blocksize;
8714 +               loc.extLocation ++;
8715 +       }
8716 +       if (UDF_SB_LVIDBH(sb) != bh)
8717 +               udf_release_data(bh);
8718 +}
8719 +
8720 +/*
8721 + * udf_process_sequence
8722 + *
8723 + * PURPOSE
8724 + *     Process a main/reserve volume descriptor sequence.
8725 + *
8726 + * PRE-CONDITIONS
8727 + *     sb                      Pointer to _locked_ superblock.
8728 + *     block                   First block of first extent of the sequence.
8729 + *     lastblock               Lastblock of first extent of the sequence.
8730 + *
8731 + * HISTORY
8732 + *     July 1, 1997 - Andrew E. Mileski
8733 + *     Written, tested, and released.
8734 + */
8735 +static  int
8736 +udf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr *fileset)
8737 +{
8738 +       struct buffer_head *bh = NULL;
8739 +       struct udf_vds_record vds[VDS_POS_LENGTH];
8740 +       struct GenericDesc *gd;
8741 +       int done=0;
8742 +       int i,j;
8743 +       Uint32 vdsn;
8744 +       Uint16 ident;
8745 +
8746 +       memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
8747 +
8748 +       /* Read the main descriptor sequence */
8749 +       for (;(!done && block <= lastblock); block++)
8750 +       {
8751 +
8752 +               bh = udf_read_tagged(sb, block, block, &ident);
8753 +               if (!bh) 
8754 +                       break;
8755 +
8756 +               /* Process each descriptor (ISO 13346 3/8.3-8.4) */
8757 +               gd = (struct GenericDesc *)bh->b_data;
8758 +               vdsn = le32_to_cpu(gd->volDescSeqNum);
8759 +               switch (ident)
8760 +               {
8761 +                       case TID_PRIMARY_VOL_DESC: /* ISO 13346 3/10.1 */
8762 +                               if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
8763 +                               {
8764 +                                       vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
8765 +                                       vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
8766 +                               }
8767 +                               break;
8768 +                       case TID_VOL_DESC_PTR: /* ISO 13346 3/10.3 */
8769 +                               if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
8770 +                               {
8771 +                                       vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
8772 +                                       vds[VDS_POS_VOL_DESC_PTR].block = block;
8773 +                               }
8774 +                               break;
8775 +                       case TID_IMP_USE_VOL_DESC: /* ISO 13346 3/10.4 */
8776 +                               if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
8777 +                               {
8778 +                                       vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
8779 +                                       vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
8780 +                               }
8781 +                               break;
8782 +                       case TID_PARTITION_DESC: /* ISO 13346 3/10.5 */
8783 +                               if (!vds[VDS_POS_PARTITION_DESC].block)
8784 +                                       vds[VDS_POS_PARTITION_DESC].block = block;
8785 +                               break;
8786 +                       case TID_LOGICAL_VOL_DESC: /* ISO 13346 3/10.6 */
8787 +                               if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
8788 +                               {
8789 +                                       vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
8790 +                                       vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
8791 +                               }
8792 +                               break;
8793 +                       case TID_UNALLOC_SPACE_DESC: /* ISO 13346 3/10.8 */
8794 +                               if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
8795 +                               {
8796 +                                       vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
8797 +                                       vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
8798 +                               }
8799 +                               break;
8800 +                       case TID_TERMINATING_DESC: /* ISO 13346 3/10.9 */
8801 +                               vds[VDS_POS_TERMINATING_DESC].block = block;
8802 +                               done = 1;
8803 +                               break;
8804 +               }
8805 +               udf_release_data(bh);
8806 +       }
8807 +       for (i=0; i<VDS_POS_LENGTH; i++)
8808 +       {
8809 +               if (vds[i].block)
8810 +               {
8811 +                       bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
8812 +
8813 +                       if (i == VDS_POS_PRIMARY_VOL_DESC)
8814 +                               udf_load_pvoldesc(sb, bh);
8815 +                       else if (i == VDS_POS_LOGICAL_VOL_DESC)
8816 +                               udf_load_logicalvol(sb, bh, fileset);
8817 +                       else if (i == VDS_POS_PARTITION_DESC)
8818 +                       {
8819 +                               struct buffer_head *bh2 = NULL;
8820 +                               udf_load_partdesc(sb, bh);
8821 +                               for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
8822 +                               {
8823 +                                       bh2 = udf_read_tagged(sb, j, j, &ident);
8824 +                                       gd = (struct GenericDesc *)bh2->b_data;
8825 +                                       if (ident == TID_PARTITION_DESC)
8826 +                                               udf_load_partdesc(sb, bh2);
8827 +                                       udf_release_data(bh2);
8828 +                               }
8829 +                       }
8830 +                       udf_release_data(bh);
8831 +               }
8832 +       }
8833 +
8834 +       return 0;
8835 +}
8836 +
8837 +/*
8838 + * udf_check_valid()
8839 + */
8840 +static int
8841 +udf_check_valid(struct super_block *sb, int novrs, int silent)
8842 +{
8843 +       long block;
8844 +
8845 +       if (novrs)
8846 +       {
8847 +               udf_debug("Validity check skipped because of novrs option\n");
8848 +               return 0;
8849 +       }
8850 +       /* Check that it is NSR02 compliant */
8851 +       /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
8852 +       else if ((block = udf_vrs(sb, silent)) == -1)
8853 +       {
8854 +               udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
8855 +               return 0;
8856 +       }
8857 +       else 
8858 +               return !block;
8859 +}
8860 +
8861 +static int
8862 +udf_load_partition(struct super_block *sb, lb_addr *fileset)
8863 +{
8864 +       struct AnchorVolDescPtr *anchor;
8865 +       Uint16 ident;
8866 +       struct buffer_head *bh;
8867 +       long main_s, main_e, reserve_s, reserve_e;
8868 +       int i, j;
8869 +
8870 +       if (!sb)
8871 +               return 1;
8872 +
8873 +       for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
8874 +       {
8875 +               if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
8876 +                       UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i] - UDF_SB_SESSION(sb), &ident)))
8877 +               {
8878 +                       anchor = (struct AnchorVolDescPtr *)bh->b_data;
8879 +
8880 +                       /* Locate the main sequence */
8881 +                       main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation );
8882 +                       main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength );
8883 +                       main_e = main_e >> sb->s_blocksize_bits;
8884 +                       main_e += main_s;
8885 +       
8886 +                       /* Locate the reserve sequence */
8887 +                       reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
8888 +                       reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
8889 +                       reserve_e = reserve_e >> sb->s_blocksize_bits;
8890 +                       reserve_e += reserve_s;
8891 +
8892 +                       udf_release_data(bh);
8893 +
8894 +                       /* Process the main & reserve sequences */
8895 +                       /* responsible for finding the PartitionDesc(s) */
8896 +                       if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
8897 +                               udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
8898 +                       {
8899 +                               break;
8900 +                       }
8901 +               }
8902 +       }
8903 +
8904 +       if (i == sizeof(UDF_SB_ANCHOR(sb))/sizeof(int))
8905 +       {
8906 +               udf_debug("No Anchor block found\n");
8907 +               return 1;
8908 +       }
8909 +       else
8910 +               udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
8911 +
8912 +       for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
8913 +       {
8914 +               switch UDF_SB_PARTTYPE(sb, i)
8915 +               {
8916 +                       case UDF_VIRTUAL_MAP15:
8917 +                       case UDF_VIRTUAL_MAP20:
8918 +                       {
8919 +                               lb_addr ino;
8920 +
8921 +                               if (!UDF_SB_LASTBLOCK(sb))
8922 +                               {
8923 +                                       udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
8924 +                                       return 1;
8925 +                               }
8926 +
8927 +                               for (j=0; j<UDF_SB_NUMPARTS(sb); j++)
8928 +                               {
8929 +                                       if (j != i &&
8930 +                                               UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) &&
8931 +                                               UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j))
8932 +                                       {
8933 +                                               ino.partitionReferenceNum = j;
8934 +                                               ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
8935 +                                                       UDF_SB_PARTROOT(sb,j);
8936 +                                               break;
8937 +                                       }
8938 +                               }
8939 +
8940 +                               if (j == UDF_SB_NUMPARTS(sb))
8941 +                                       return 1;
8942 +
8943 +                               if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
8944 +                                       return 1;
8945 +
8946 +                               if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
8947 +                               {
8948 +                                       UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb));
8949 +                                       UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
8950 +                               }
8951 +                               else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
8952 +                               {
8953 +                                       struct buffer_head *bh = NULL;
8954 +                                       Uint32 pos;
8955 +
8956 +                                       pos = udf_bmap(UDF_SB_VAT(sb), 0);
8957 +                                       bh = bread(sb->s_dev, pos, sb->s_blocksize);
8958 +                                       UDF_SB_TYPEVIRT(sb,i).s_start_offset =
8959 +                                               le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
8960 +                                                       udf_ext0_offset(UDF_SB_VAT(sb));
8961 +                                       UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
8962 +                                               UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
8963 +                                       udf_release_data(bh);
8964 +                               }
8965 +                               UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
8966 +                               UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
8967 +                       }
8968 +               }
8969 +       }
8970 +       return 0;
8971 +}
8972 +
8973 +static void udf_open_lvid(struct super_block *sb)
8974 +{
8975 +       if (UDF_SB_LVIDBH(sb))
8976 +       {
8977 +               int i;
8978 +               timestamp cpu_time;
8979 +
8980 +               UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
8981 +               UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
8982 +               if (udf_time_to_stamp(&cpu_time, CURRENT_TIME, CURRENT_UTIME))
8983 +                       UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
8984 +               UDF_SB_LVID(sb)->integrityType = INTEGRITY_TYPE_OPEN;
8985 +
8986 +               UDF_SB_LVID(sb)->descTag.descCRC =
8987 +                       cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
8988 +                       le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
8989 +
8990 +               UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
8991 +               for (i=0; i<16; i++)
8992 +                       if (i != 4)
8993 +                               UDF_SB_LVID(sb)->descTag.tagChecksum +=
8994 +                                       ((Uint8 *)&(UDF_SB_LVID(sb)->descTag))[i];
8995 +
8996 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
8997 +       }
8998 +}
8999 +
9000 +static void udf_close_lvid(struct super_block *sb)
9001 +{
9002 +       if (UDF_SB_LVIDBH(sb) &&
9003 +               UDF_SB_LVID(sb)->integrityType == INTEGRITY_TYPE_OPEN)
9004 +       {
9005 +               int i;
9006 +               timestamp cpu_time;
9007 +
9008 +               UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
9009 +               UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
9010 +               if (udf_time_to_stamp(&cpu_time, CURRENT_TIME, CURRENT_UTIME))
9011 +                       UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
9012 +               if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
9013 +                       UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
9014 +               if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
9015 +                       UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
9016 +               if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
9017 +                       UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
9018 +               UDF_SB_LVID(sb)->integrityType = INTEGRITY_TYPE_CLOSE;
9019 +
9020 +               UDF_SB_LVID(sb)->descTag.descCRC =
9021 +                       cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
9022 +                       le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
9023 +
9024 +               UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
9025 +               for (i=0; i<16; i++)
9026 +                       if (i != 4)
9027 +                               UDF_SB_LVID(sb)->descTag.tagChecksum +=
9028 +                                       ((Uint8 *)&(UDF_SB_LVID(sb)->descTag))[i];
9029 +
9030 +               mark_buffer_dirty(UDF_SB_LVIDBH(sb), 1);
9031 +       }
9032 +}
9033 +
9034 +/*
9035 + * udf_read_super
9036 + *
9037 + * PURPOSE
9038 + *     Complete the specified super block.
9039 + *
9040 + * PRE-CONDITIONS
9041 + *     sb                      Pointer to superblock to complete - never NULL.
9042 + *     sb->s_dev               Device to read suberblock from.
9043 + *     options                 Pointer to mount options.
9044 + *     silent                  Silent flag.
9045 + *
9046 + * HISTORY
9047 + *     July 1, 1997 - Andrew E. Mileski
9048 + *     Written, tested, and released.
9049 + */
9050 +static struct super_block *
9051 +udf_read_super(struct super_block *sb, void *options, int silent)
9052 +{
9053 +       struct inode *inode=NULL;
9054 +       struct udf_options uopt;
9055 +       lb_addr rootdir, fileset;
9056 +
9057 +       uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
9058 +       uopt.uid = 0;
9059 +       uopt.gid = 0;
9060 +       uopt.umask = 0;
9061 +
9062 +       /* Lock the module in memory (if applicable) */
9063 +       MOD_INC_USE_COUNT;
9064 +
9065 +       lock_super(sb);
9066 +       UDF_SB_ALLOC(sb); /* kmalloc, if needed */
9067 +       memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
9068 +
9069 +#if CONFIG_UDF_RW != 1
9070 +       sb->s_flags |= MS_RDONLY;
9071 +#endif
9072 +
9073 +       if (!udf_parse_options((char *)options, &uopt))
9074 +               goto error_out;
9075 +
9076 +       fileset.logicalBlockNum = 0xFFFFFFFF;
9077 +       fileset.partitionReferenceNum = 0xFFFF;
9078 +
9079 +       UDF_SB(sb)->s_flags = uopt.flags;
9080 +       UDF_SB(sb)->s_uid = uopt.uid;
9081 +       UDF_SB(sb)->s_gid = uopt.gid;
9082 +       UDF_SB(sb)->s_umask = uopt.umask;
9083 +
9084 +       /* Set the block size for all transfers */
9085 +       if (!udf_set_blocksize(sb, uopt.blocksize))
9086 +               goto error_out;
9087 +
9088 +       if ( uopt.session == 0xFFFFFFFF )
9089 +               UDF_SB_SESSION(sb) = udf_get_last_session(sb);
9090 +       else
9091 +               UDF_SB_SESSION(sb) = uopt.session;
9092 +
9093 +       udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
9094 +
9095 +       if ( uopt.lastblock == 0xFFFFFFFF )
9096 +               UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
9097 +       else
9098 +               UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
9099 +
9100 +       UDF_SB_LASTBLOCK(sb) = udf_find_anchor(sb, uopt.anchor, UDF_SB_LASTBLOCK(sb));
9101 +
9102 +       udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
9103 +
9104 +       if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
9105 +       {
9106 +               printk("UDF-fs: No VRS found\n");
9107 +               goto error_out;
9108 +       }
9109 +
9110 +       /* Fill in the rest of the superblock */
9111 +       sb->s_op = &udf_sb_ops;
9112 +       sb->dq_op = NULL;
9113 +       sb->s_dirt = 0;
9114 +       sb->s_magic = UDF_SUPER_MAGIC;
9115 +
9116 +       if (udf_load_partition(sb, &fileset))
9117 +       {
9118 +               printk("UDF-fs: No partition found (1)\n");
9119 +               goto error_out;
9120 +       }
9121 +
9122 +       if ( UDF_SB_LVIDBH(sb) )
9123 +       {
9124 +               Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
9125 +               Uint16 minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
9126 +               /* Uint16 maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
9127 +
9128 +               if (minUDFReadRev > UDF_MAX_READ_VERSION)
9129 +               {
9130 +                       printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
9131 +                               UDF_SB_LVIDIU(sb)->minUDFReadRev, UDF_MAX_READ_VERSION);
9132 +                       goto error_out;
9133 +               }
9134 +               else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
9135 +               {
9136 +                       sb->s_flags |= MS_RDONLY;
9137 +               }
9138 +
9139 +               if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
9140 +                       UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
9141 +               if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
9142 +                       UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
9143 +       }
9144 +
9145 +       if ( !UDF_SB_NUMPARTS(sb) )
9146 +       {
9147 +               printk("UDF-fs: No partition found (2)\n");
9148 +               goto error_out;
9149 +       }
9150 +
9151 +       if ( udf_find_fileset(sb, &fileset, &rootdir) )
9152 +       {
9153 +               printk("UDF-fs: No fileset found\n");
9154 +               goto error_out;
9155 +       }
9156 +
9157 +       if (!silent)
9158 +       {
9159 +               timestamp ts;
9160 +               udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
9161 +               udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
9162 +                       UDFFS_VERSION, UDFFS_DATE,
9163 +                       UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
9164 +                       ts.typeAndTimezone);
9165 +       }
9166 +       if (!(sb->s_flags & MS_RDONLY))
9167 +               udf_open_lvid(sb);
9168 +       unlock_super(sb);
9169 +
9170 +       /* Assign the root inode */
9171 +       /* assign inodes by physical block number */
9172 +       /* perhaps it's not extensible enough, but for now ... */
9173 +       inode = udf_iget(sb, rootdir); 
9174 +       if (!inode)
9175 +       {
9176 +               printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n",
9177 +                       rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
9178 +               goto error_out;
9179 +       }
9180 +
9181 +       /* Allocate a dentry for the root inode */
9182 +       sb->s_root = d_alloc_root(inode, NULL);
9183 +       if (!sb->s_root)
9184 +       {
9185 +               printk("UDF-fs: Couldn't allocate root dentry\n");
9186 +               iput(inode);
9187 +               goto error_out;
9188 +       }
9189 +
9190 +       return sb;
9191 +
9192 +error_out:
9193 +       sb->s_dev = NODEV;
9194 +       if (UDF_SB_VAT(sb))
9195 +               iput(UDF_SB_VAT(sb));
9196 +       if (UDF_SB_NUMPARTS(sb))
9197 +       {
9198 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
9199 +                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
9200 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
9201 +                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
9202 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
9203 +                       kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
9204 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
9205 +                       kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
9206 +       }
9207 +       if (!(sb->s_flags & MS_RDONLY))
9208 +               udf_close_lvid(sb);
9209 +       udf_release_data(UDF_SB_LVIDBH(sb));
9210 +       UDF_SB_FREE(sb);
9211 +       unlock_super(sb);
9212 +       MOD_DEC_USE_COUNT;
9213 +       return NULL;
9214 +}
9215 +
9216 +void udf_error(struct super_block *sb, const char *function,
9217 +       const char *fmt, ...)
9218 +{
9219 +       va_list args;
9220 +
9221 +       if (!(sb->s_flags & MS_RDONLY))
9222 +       {
9223 +               /* mark sb error */
9224 +               sb->s_dirt = 1;
9225 +       }
9226 +       va_start(args, fmt);
9227 +       vsprintf(error_buf, fmt, args);
9228 +       va_end(args);
9229 +       printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
9230 +               bdevname(sb->s_dev), function, error_buf);
9231 +}
9232 +
9233 +void udf_warning(struct super_block *sb, const char *function,
9234 +       const char *fmt, ...)
9235 +{
9236 +       va_list args;
9237 +
9238 +       va_start (args, fmt);
9239 +       vsprintf(error_buf, fmt, args);
9240 +       va_end(args);
9241 +       printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
9242 +               bdevname(sb->s_dev), function, error_buf);
9243 +}
9244 +
9245 +/*
9246 + * udf_put_super
9247 + *
9248 + * PURPOSE
9249 + *     Prepare for destruction of the superblock.
9250 + *
9251 + * DESCRIPTION
9252 + *     Called before the filesystem is unmounted.
9253 + *
9254 + * HISTORY
9255 + *     July 1, 1997 - Andrew E. Mileski
9256 + *     Written, tested, and released.
9257 + */
9258 +static void
9259 +udf_put_super(struct super_block *sb)
9260 +{
9261 +       int i;
9262 +
9263 +       if (UDF_SB_VAT(sb))
9264 +               iput(UDF_SB_VAT(sb));
9265 +       if (UDF_SB_NUMPARTS(sb))
9266 +       {
9267 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
9268 +                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
9269 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
9270 +                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
9271 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
9272 +               {
9273 +                       for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_uspace); i++)
9274 +                       {
9275 +                               if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i))
9276 +                                       udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i));
9277 +                       }
9278 +                       kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
9279 +               }
9280 +               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
9281 +               {
9282 +                       for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_fspace); i++)
9283 +                       {
9284 +                               if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i))
9285 +                                       udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i));
9286 +                       }
9287 +                       kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
9288 +               }
9289 +       }
9290 +       if (!(sb->s_flags & MS_RDONLY))
9291 +               udf_close_lvid(sb);
9292 +       udf_release_data(UDF_SB_LVIDBH(sb));
9293 +       UDF_SB_FREE(sb);
9294 +
9295 +       MOD_DEC_USE_COUNT;
9296 +}
9297 +
9298 +/*
9299 + * udf_stat_fs
9300 + *
9301 + * PURPOSE
9302 + *     Return info about the filesystem.
9303 + *
9304 + * DESCRIPTION
9305 + *     Called by sys_statfs()
9306 + *
9307 + * HISTORY
9308 + *     July 1, 1997 - Andrew E. Mileski
9309 + *     Written, tested, and released.
9310 + */
9311 +static int
9312 +udf_statfs(struct super_block *sb, struct statfs *buf, int bufsize)
9313 +{
9314 +       int size;
9315 +       struct statfs tmp;
9316 +       int rc;
9317 +
9318 +       size = (bufsize < sizeof(tmp)) ? bufsize: sizeof(tmp);
9319 +
9320 +       memset(&tmp, 0, sizeof(tmp));
9321 +       tmp.f_type = UDF_SUPER_MAGIC;
9322 +       tmp.f_bsize = sb->s_blocksize;
9323 +       tmp.f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
9324 +       tmp.f_bfree = udf_count_free(sb);
9325 +       tmp.f_bavail = tmp.f_bfree;
9326 +       tmp.f_files = (UDF_SB_LVIDBH(sb) ?
9327 +               (le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
9328 +               le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + tmp.f_bfree;
9329 +       tmp.f_ffree = tmp.f_bfree;
9330 +       /* __kernel_fsid_t f_fsid */
9331 +       tmp.f_namelen = UDF_NAME_LEN;
9332 +
9333 +       rc= copy_to_user(buf, &tmp, size) ? -EFAULT: 0;
9334 +       return rc;
9335 +}
9336 +
9337 +static unsigned char udf_bitmap_lookup[16] = {
9338 +       0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
9339 +};
9340 +
9341 +static unsigned int
9342 +udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
9343 +{
9344 +       struct buffer_head *bh = NULL;
9345 +       unsigned int accum = 0;
9346 +       int index;
9347 +       int block = 0, newblock;
9348 +       lb_addr loc;
9349 +       Uint32 bytes;
9350 +       Uint8 value;
9351 +       Uint8 *ptr;
9352 +       Uint16 ident;
9353 +       struct SpaceBitmapDesc *bm;
9354 +
9355 +       loc.logicalBlockNum = bitmap->s_extPosition;
9356 +       loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
9357 +       bh = udf_read_ptagged(sb, loc, 0, &ident);
9358 +
9359 +       if (!bh)
9360 +       {
9361 +               printk(KERN_ERR "udf: udf_count_free failed\n");
9362 +               return 0;
9363 +       }
9364 +       else if (ident != TID_SPACE_BITMAP_DESC)
9365 +       {
9366 +               udf_release_data(bh);
9367 +               printk(KERN_ERR "udf: udf_count_free failed\n");
9368 +               return 0;
9369 +       }
9370 +
9371 +       bm = (struct SpaceBitmapDesc *)bh->b_data;
9372 +       bytes = bm->numOfBytes;
9373 +       index = sizeof(struct SpaceBitmapDesc); /* offset in first block only */
9374 +       ptr = (Uint8 *)bh->b_data;
9375 +
9376 +       while ( bytes > 0 )
9377 +       {
9378 +               while ((bytes > 0) && (index < sb->s_blocksize))
9379 +               {
9380 +                       value = ptr[index];
9381 +                       accum += udf_bitmap_lookup[ value & 0x0f ];
9382 +                       accum += udf_bitmap_lookup[ value >> 4 ];
9383 +                       index++;
9384 +                       bytes--;
9385 +               }
9386 +               if ( bytes )
9387 +               {
9388 +                       udf_release_data(bh);
9389 +                       newblock = udf_get_lb_pblock(sb, loc, ++block);
9390 +                       bh = udf_tread(sb, newblock, sb->s_blocksize);
9391 +                       if (!bh)
9392 +                       {
9393 +                               udf_debug("read failed\n");
9394 +                               return accum;
9395 +                       }
9396 +                       index = 0;
9397 +                       ptr = (Uint8 *)bh->b_data;
9398 +               }
9399 +       }
9400 +       udf_release_data(bh);
9401 +       return accum;
9402 +}
9403 +
9404 +static unsigned int
9405 +udf_count_free_table(struct super_block *sb, struct inode * table)
9406 +{
9407 +       unsigned int accum = 0;
9408 +       Uint32 extoffset, elen;
9409 +       lb_addr bloc, eloc;
9410 +       char etype;
9411 +       struct buffer_head *bh = NULL;
9412 +
9413 +       bloc = UDF_I_LOCATION(table);
9414 +       extoffset = sizeof(struct UnallocatedSpaceEntry);
9415 +
9416 +       while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
9417 +       {
9418 +               accum += (elen >> table->i_sb->s_blocksize_bits);
9419 +       }
9420 +       udf_release_data(bh);
9421 +       return accum;
9422 +}
9423 +       
9424 +static unsigned int
9425 +udf_count_free(struct super_block *sb)
9426 +{
9427 +       unsigned int accum = 0;
9428 +
9429 +       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
9430 +       {
9431 +               accum += udf_count_free_bitmap(sb,
9432 +                       UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
9433 +       }
9434 +       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
9435 +       {
9436 +               accum += udf_count_free_bitmap(sb,
9437 +                       UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
9438 +       }
9439 +       if (accum)
9440 +               return accum;
9441 +
9442 +       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
9443 +       {
9444 +               accum += udf_count_free_table(sb,
9445 +                       UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
9446 +       }
9447 +       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
9448 +       {
9449 +               accum += udf_count_free_table(sb,
9450 +                       UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
9451 +       }
9452 +       if (accum)
9453 +               return accum;
9454 +
9455 +       if (UDF_SB_LVIDBH(sb))
9456 +       {
9457 +               if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
9458 +               {
9459 +                       accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
9460 +
9461 +                       if (accum == 0xFFFFFFFF)
9462 +                               accum = 0;
9463 +               }
9464 +       }
9465 +       return accum;
9466 +}
9467 diff -Nru linux/fs/udf/symlink.c linux.new/fs/udf/symlink.c
9468 --- linux/fs/udf/symlink.c      Thu Jan  1 01:00:00 1970
9469 +++ linux.new/fs/udf/symlink.c  Fri Sep  7 11:32:16 2001
9470 @@ -0,0 +1,181 @@
9471 +/*
9472 + * symlink.c
9473 + *
9474 + * PURPOSE
9475 + *     Symlink handling routines for the OSTA-UDF(tm) filesystem.
9476 + *
9477 + * CONTACTS
9478 + *     E-mail regarding any portion of the Linux UDF file system should be
9479 + *     directed to the development team mailing list (run by majordomo):
9480 + *             linux_udf@hootie.lvld.hp.com
9481 + *
9482 + * COPYRIGHT
9483 + *     This file is distributed under the terms of the GNU General Public
9484 + *     License (GPL). Copies of the GPL can be obtained from:
9485 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
9486 + *     Each contributing author retains all rights to their own work.
9487 + *
9488 + *  (C) 1998-2000 Ben Fennema
9489 + *  (C) 1999 Stelias Computing Inc 
9490 + *
9491 + * HISTORY
9492 + *
9493 + *  04/16/99 blf  Created.
9494 + *
9495 + */
9496 +
9497 +#include "udfdecl.h"
9498 +#include <asm/uaccess.h>
9499 +#include <linux/errno.h>
9500 +#include <linux/fs.h>
9501 +#include <linux/udf_fs.h>
9502 +#include <linux/sched.h>
9503 +#include <linux/mm.h>
9504 +#include <linux/stat.h>
9505 +#include <linux/malloc.h>
9506 +#include "udf_i.h"
9507 +
9508 +static void udf_pc_to_char(char *from, int fromlen, char *to)
9509 +{
9510 +       struct PathComponent *pc;
9511 +       int elen = 0;
9512 +       char *p = to;
9513 +
9514 +       while (elen < fromlen)
9515 +       {
9516 +               pc = (struct PathComponent *)(from + elen);
9517 +               switch (pc->componentType)
9518 +               {
9519 +                       case 1:
9520 +                               if (pc->lengthComponentIdent == 0)
9521 +                               {
9522 +                                       p = to;
9523 +                                       *p++ = '/';
9524 +                               }
9525 +                               break;
9526 +                       case 3:
9527 +                               memcpy(p, "../", 3);
9528 +                               p += 3;
9529 +                               break;
9530 +                       case 4:
9531 +                               memcpy(p, "./", 2);
9532 +                               p += 2;
9533 +                               /* that would be . - just ignore */
9534 +                               break;
9535 +                       case 5:
9536 +                               memcpy(p, pc->componentIdent, pc->lengthComponentIdent);
9537 +                               p += pc->lengthComponentIdent;
9538 +                               *p++ = '/';
9539 +               }
9540 +               elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
9541 +       }
9542 +       if (p > to+1)
9543 +               p[-1] = '\0';
9544 +       else
9545 +               p[0] = '\0';
9546 +}
9547 +
9548 +static struct dentry * udf_follow_link(struct dentry * dentry,
9549 +       struct dentry * base, unsigned int follow)
9550 +{
9551 +       struct inode *inode = dentry->d_inode;
9552 +       struct buffer_head *bh = NULL;
9553 +       char *symlink, *tmpbuf;
9554 +       
9555 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
9556 +       {
9557 +               bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
9558 +
9559 +               if (!bh)
9560 +                       return 0;
9561 +
9562 +               symlink = bh->b_data + udf_file_entry_alloc_offset(inode);
9563 +       }
9564 +       else
9565 +       {
9566 +               bh = bread(inode->i_dev, udf_bmap(inode, 0), inode->i_sb->s_blocksize);
9567 +
9568 +               if (!bh)
9569 +                       return 0;
9570 +
9571 +               symlink = bh->b_data;
9572 +       }
9573 +       if ((tmpbuf = (char *)kmalloc(inode->i_size, GFP_KERNEL)))
9574 +       {
9575 +               udf_pc_to_char(symlink, inode->i_size, tmpbuf);
9576 +               base = lookup_dentry(tmpbuf, base, follow);
9577 +               kfree(tmpbuf);
9578 +               return base;
9579 +       }
9580 +       else
9581 +               return ERR_PTR(-ENOMEM);
9582 +}
9583 +
9584 +static int udf_readlink(struct dentry * dentry, char * buffer, int buflen)
9585 +{
9586 +       struct inode *inode = dentry->d_inode;
9587 +       struct buffer_head *bh = NULL;
9588 +       char *symlink, *tmpbuf;
9589 +       int len;
9590 +       
9591 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
9592 +       {
9593 +               bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
9594 +
9595 +               if (!bh)
9596 +                       return 0;
9597 +
9598 +               symlink = bh->b_data + udf_file_entry_alloc_offset(inode);
9599 +       }
9600 +       else
9601 +       {
9602 +               bh = bread(inode->i_dev, udf_bmap(inode, 0), inode->i_sb->s_blocksize);
9603 +
9604 +               if (!bh)
9605 +                       return 0;
9606 +
9607 +               symlink = bh->b_data;
9608 +       }
9609 +
9610 +       if ((tmpbuf = (char *)kmalloc(inode->i_size, GFP_KERNEL)))
9611 +       {
9612 +               udf_pc_to_char(symlink, inode->i_size, tmpbuf);
9613 +               if ((len = strlen(tmpbuf)) > buflen)
9614 +                       len = buflen;
9615 +               if (copy_to_user(buffer, tmpbuf, len))
9616 +                       len = -EFAULT;
9617 +               kfree(tmpbuf);
9618 +       }
9619 +       else
9620 +               len = -ENOMEM;
9621 +
9622 +       UPDATE_ATIME(inode);
9623 +       if (bh)
9624 +               udf_release_data(bh);
9625 +       return len;
9626 +}
9627 +
9628 +/*
9629 + * symlinks can't do much...
9630 + */
9631 +struct inode_operations udf_symlink_inode_operations = {
9632 +       NULL,                   /* no file-operations */
9633 +       NULL,                   /* create */
9634 +       NULL,                   /* lookup */
9635 +       NULL,                   /* link */
9636 +       NULL,                   /* unlink */
9637 +       NULL,                   /* symlink */
9638 +       NULL,                   /* mkdir */
9639 +       NULL,                   /* rmdir */
9640 +       NULL,                   /* mknod */
9641 +       NULL,                   /* rename */
9642 +       udf_readlink,   /* readlink */
9643 +       udf_follow_link,/* follow_link */
9644 +       NULL,                   /* readpage */
9645 +       NULL,                   /* writepage */
9646 +       NULL,                   /* bmap */
9647 +       NULL,                   /* truncate */
9648 +       NULL,                   /* permission */
9649 +       NULL,                   /* smap */
9650 +       NULL                    /* revalidate */
9651 +};
9652 diff -Nru linux/fs/udf/truncate.c linux.new/fs/udf/truncate.c
9653 --- linux/fs/udf/truncate.c     Thu Jan  1 01:00:00 1970
9654 +++ linux.new/fs/udf/truncate.c Fri Sep  7 11:32:16 2001
9655 @@ -0,0 +1,288 @@
9656 +/*
9657 + * truncate.c
9658 + *
9659 + * PURPOSE
9660 + *     Truncate handling routines for the OSTA-UDF(tm) filesystem.
9661 + *
9662 + * CONTACTS
9663 + *     E-mail regarding any portion of the Linux UDF file system should be
9664 + *     directed to the development team mailing list (run by majordomo):
9665 + *             linux_udf@hootie.lvld.hp.com
9666 + *
9667 + * COPYRIGHT
9668 + *     This file is distributed under the terms of the GNU General Public
9669 + *     License (GPL). Copies of the GPL can be obtained from:
9670 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
9671 + *     Each contributing author retains all rights to their own work.
9672 + *
9673 + *  (C) 1999-2000 Ben Fennema
9674 + *  (C) 1999 Stelias Computing Inc
9675 + *
9676 + * HISTORY
9677 + *
9678 + *  02/24/99 blf  Created.
9679 + *
9680 + */
9681 +
9682 +#include "udfdecl.h"
9683 +#include <linux/fs.h>
9684 +#include <linux/mm.h>
9685 +#include <linux/udf_fs.h>
9686 +
9687 +#include "udf_i.h"
9688 +#include "udf_sb.h"
9689 +
9690 +static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
9691 +       lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head *bh, Uint32 nelen)
9692 +{
9693 +       lb_addr neloc = { 0, 0 };
9694 +       int blocks = inode->i_sb->s_blocksize / 512;
9695 +       int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
9696 +       int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
9697 +
9698 +       if (nelen)
9699 +       {
9700 +               neloc = eloc;
9701 +               nelen = (etype << 30) | nelen;
9702 +       }
9703 +               
9704 +       if (elen != nelen)
9705 +       {
9706 +               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
9707 +               if (last_block - first_block > 0)
9708 +               {
9709 +                       if (etype == EXTENT_RECORDED_ALLOCATED)
9710 +                       {
9711 +                               inode->i_blocks -= (blocks * (last_block - first_block));
9712 +                               mark_inode_dirty(inode);
9713 +                       }
9714 +                       if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
9715 +                               udf_free_blocks(inode, eloc, first_block, last_block - first_block);
9716 +               }
9717 +       }
9718 +}
9719 +
9720 +void udf_trunc(struct inode * inode)
9721 +{
9722 +       lb_addr bloc, eloc, neloc = { 0, 0 };
9723 +       Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
9724 +       int etype;
9725 +       int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
9726 +       struct buffer_head *bh = NULL;
9727 +       int adsize;
9728 +
9729 +       if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
9730 +               adsize = sizeof(short_ad);
9731 +       else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
9732 +               adsize = sizeof(long_ad);
9733 +       else
9734 +               adsize = 0;
9735 +
9736 +       etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
9737 +       offset = (offset << inode->i_sb->s_blocksize_bits) |
9738 +               (inode->i_size & (inode->i_sb->s_blocksize - 1));
9739 +       if (etype != -1)
9740 +       {
9741 +               extoffset -= adsize;
9742 +               extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
9743 +               extoffset += adsize;
9744 +
9745 +               if (offset)
9746 +                       lenalloc = extoffset;
9747 +               else
9748 +                       lenalloc = extoffset - adsize;
9749 +
9750 +               if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
9751 +                       lenalloc -= udf_file_entry_alloc_offset(inode);
9752 +               else
9753 +                       lenalloc -= sizeof(struct AllocExtDesc);
9754 +
9755 +               while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
9756 +               {
9757 +                       if (etype == EXTENT_NEXT_EXTENT_ALLOCDECS)
9758 +                       {
9759 +                               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
9760 +                               extoffset = 0;
9761 +                               if (lelen)
9762 +                               {
9763 +                                       if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
9764 +                                               memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
9765 +                                       else
9766 +                                               memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
9767 +                                       udf_free_blocks(inode, bloc, 0, lelen);
9768 +                               }
9769 +                               else
9770 +                               {
9771 +                                       if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
9772 +                                       {
9773 +                                               UDF_I_LENALLOC(inode) = lenalloc;
9774 +                                               mark_inode_dirty(inode);
9775 +                                       }
9776 +                                       else
9777 +                                       {
9778 +                                               struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
9779 +                                               aed->lengthAllocDescs = cpu_to_le32(lenalloc);
9780 +                                               udf_update_tag(bh->b_data, lenalloc +
9781 +                                                       sizeof(struct AllocExtDesc));
9782 +                                               mark_buffer_dirty(bh, 1);
9783 +                                       }
9784 +                               }
9785 +
9786 +                               udf_release_data(bh);
9787 +                               bh = NULL;
9788 +
9789 +                               bloc = eloc;
9790 +                               if (elen)
9791 +                                       lelen = (elen + inode->i_sb->s_blocksize - 1) >>
9792 +                                               inode->i_sb->s_blocksize_bits;
9793 +                               else
9794 +                                       lelen = 1;
9795 +                       }
9796 +                       else
9797 +                       {
9798 +                               extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
9799 +                               extoffset += adsize;
9800 +                       }
9801 +               }
9802 +
9803 +               if (lelen)
9804 +               {
9805 +                       if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
9806 +                               memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
9807 +                       else
9808 +                               memset(bh->b_data, 0x00, sizeof(struct AllocExtDesc));
9809 +                       udf_free_blocks(inode, bloc, 0, lelen);
9810 +               }
9811 +               else
9812 +               {
9813 +                       if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
9814 +                       {
9815 +                               UDF_I_LENALLOC(inode) = lenalloc;
9816 +                               mark_inode_dirty(inode);
9817 +                       }
9818 +                       else
9819 +                       {
9820 +                               struct AllocExtDesc *aed = (struct AllocExtDesc *)(bh->b_data);
9821 +                               aed->lengthAllocDescs = cpu_to_le32(lenalloc);
9822 +                               udf_update_tag(bh->b_data, lenalloc +
9823 +                                       sizeof(struct AllocExtDesc));
9824 +                               mark_buffer_dirty(bh, 1);
9825 +                       }
9826 +               }
9827 +       }
9828 +       else if (inode->i_size)
9829 +       {
9830 +               if (offset)
9831 +               {
9832 +                       extoffset -= adsize;
9833 +                       etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
9834 +
9835 +                       if (etype == EXTENT_NOT_RECORDED_NOT_ALLOCATED)
9836 +                       {
9837 +                               extoffset -= adsize;
9838 +                               elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | (elen + offset);
9839 +                               udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
9840 +                       }
9841 +                       else if (etype == EXTENT_NOT_RECORDED_ALLOCATED)
9842 +                       {
9843 +                               lb_addr neloc = { 0, 0 };
9844 +                               extoffset -= adsize;
9845 +                               nelen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
9846 +                                       ((elen + offset + inode->i_sb->s_blocksize - 1) &
9847 +                                       ~(inode->i_sb->s_blocksize - 1));
9848 +                               udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
9849 +                               udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
9850 +                       }
9851 +                       else
9852 +                       {
9853 +                               if (elen & (inode->i_sb->s_blocksize - 1))
9854 +                               {
9855 +                                       extoffset -= adsize;
9856 +                                       elen = (EXTENT_RECORDED_ALLOCATED << 30) |
9857 +                                               ((elen + inode->i_sb->s_blocksize - 1) &
9858 +                                               ~(inode->i_sb->s_blocksize - 1));
9859 +                                       udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
9860 +                               }
9861 +                               memset(&eloc, 0x00, sizeof(lb_addr));
9862 +                               elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) | offset;
9863 +                               udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
9864 +                       }
9865 +               }
9866 +       }
9867 +
9868 +       udf_release_data(bh);
9869 +}
9870 +
9871 +void udf_truncate(struct inode * inode)
9872 +{
9873 +       int offset;
9874 +
9875 +       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
9876 +                       S_ISLNK(inode->i_mode)))
9877 +               return;
9878 +       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
9879 +               return;
9880 +
9881 +       udf_trunc(inode);
9882 +
9883 +       offset = (inode->i_size & (inode->i_sb->s_blocksize - 1));
9884 +       if (offset)
9885 +       {
9886 +               struct buffer_head *bh;
9887 +               bh = bread(inode->i_dev,
9888 +                       udf_bmap(inode, inode->i_size >> inode->i_sb->s_blocksize_bits),
9889 +                       inode->i_sb->s_blocksize);
9890 +               if (bh)
9891 +               {
9892 +                       memset(bh->b_data + offset, 0x00, inode->i_sb->s_blocksize - offset);
9893 +                       mark_buffer_dirty(bh, 0);
9894 +                       udf_release_data(bh);
9895 +               }
9896 +       }
9897 +
9898 +       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
9899 +       mark_inode_dirty(inode);
9900 +}
9901 +
9902 +void udf_truncate_adinicb(struct inode * inode)
9903 +{
9904 +       int offset;
9905 +       struct buffer_head *bh;
9906 +       int err;
9907 +
9908 +       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
9909 +                       S_ISLNK(inode->i_mode)))
9910 +               return;
9911 +       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
9912 +               return;
9913 +
9914 +       if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
9915 +                       inode->i_size))
9916 +       {
9917 +               udf_expand_file_adinicb(inode, inode->i_size, &err);
9918 +               if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
9919 +               {
9920 +                       inode->i_size = UDF_I_LENALLOC(inode);
9921 +                       return;
9922 +               }
9923 +               else
9924 +                       return udf_truncate(inode);
9925 +       }
9926 +       else
9927 +               UDF_I_LENALLOC(inode) = inode->i_size;
9928 +
9929 +       offset = (inode->i_size & (inode->i_sb->s_blocksize - 1)) +
9930 +               udf_file_entry_alloc_offset(inode);
9931 +
9932 +       if ((bh = udf_tread(inode->i_sb,
9933 +               udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
9934 +               inode->i_sb->s_blocksize)))
9935 +       {
9936 +               memset(bh->b_data + offset, 0x00, inode->i_sb->s_blocksize - offset);
9937 +               mark_buffer_dirty(bh, 0);
9938 +               udf_release_data(bh);
9939 +       }
9940 +
9941 +       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
9942 +       mark_inode_dirty(inode);
9943 +}
9944 diff -Nru linux/fs/udf/udf_i.h linux.new/fs/udf/udf_i.h
9945 --- linux/fs/udf/udf_i.h        Thu Jan  1 01:00:00 1970
9946 +++ linux.new/fs/udf/udf_i.h    Fri Sep  7 11:32:16 2001
9947 @@ -0,0 +1,29 @@
9948 +#ifndef __LINUX_UDF_I_H
9949 +#define __LINUX_UDF_I_H
9950 +
9951 +#ifndef CONFIG_UDF_FS_EXT
9952 +
9953 +#define UDF_I(X)       (&((X)->u.udf_i))
9954 +
9955 +#else
9956 +/* we're not compiled in, so we can't expect our stuff in <linux/fs.h> */
9957 +#define UDF_I(X)       ( (struct udf_inode_info *) &((X)->u.pipe_i))
9958 +       /* god, this is slimy. stealing another filesystem's union area. */
9959 +       /* for the record, pipe_i is 9 ints long, we're using 9          */
9960 +#endif
9961 +
9962 +#define UDF_I_LOCATION(X)      ( UDF_I(X)->i_location )
9963 +#define UDF_I_LENEATTR(X)      ( UDF_I(X)->i_lenEAttr )
9964 +#define UDF_I_LENALLOC(X)      ( UDF_I(X)->i_lenAlloc )
9965 +#define UDF_I_UNIQUE(X)                ( UDF_I(X)->i_unique )
9966 +#define UDF_I_ALLOCTYPE(X)     ( UDF_I(X)->i_alloc_type )
9967 +#define UDF_I_EXTENDED_FE(X)( UDF_I(X)->i_extended_fe )
9968 +#define UDF_I_STRAT4096(X)     ( UDF_I(X)->i_strat_4096 )
9969 +#define UDF_I_NEW_INODE(X)     ( UDF_I(X)->i_new_inode )
9970 +#define UDF_I_NEXT_ALLOC_BLOCK(X)      ( UDF_I(X)->i_next_alloc_block )
9971 +#define UDF_I_NEXT_ALLOC_GOAL(X)       ( UDF_I(X)->i_next_alloc_goal )
9972 +#define UDF_I_UATIME(X)                ( UDF_I(X)->i_uatime )
9973 +#define UDF_I_UMTIME(X)                ( UDF_I(X)->i_umtime )
9974 +#define UDF_I_UCTIME(X)                ( UDF_I(X)->i_uctime )
9975 +
9976 +#endif /* !defined(_LINUX_UDF_I_H) */
9977 diff -Nru linux/fs/udf/udf_sb.h linux.new/fs/udf/udf_sb.h
9978 --- linux/fs/udf/udf_sb.h       Thu Jan  1 01:00:00 1970
9979 +++ linux.new/fs/udf/udf_sb.h   Fri Sep  7 11:32:16 2001
9980 @@ -0,0 +1,125 @@
9981 +#ifndef __LINUX_UDF_SB_H
9982 +#define __LINUX_UDF_SB_H
9983 +
9984 +/* Since UDF 1.50 is ISO 13346 based... */
9985 +#define UDF_SUPER_MAGIC                                0x15013346
9986 +
9987 +#define UDF_MAX_READ_VERSION           0x0200
9988 +#define UDF_MAX_WRITE_VERSION          0x0200
9989 +
9990 +#define UDF_FLAG_USE_EXTENDED_FE       0
9991 +#define UDF_VERS_USE_EXTENDED_FE       0x0200
9992 +#define UDF_FLAG_USE_STREAMS           1
9993 +#define UDF_VERS_USE_STREAMS           0x0200
9994 +#define UDF_FLAG_USE_SHORT_AD          2
9995 +#define UDF_FLAG_USE_AD_IN_ICB         3
9996 +#define UDF_FLAG_USE_FILE_CTIME_EA     4
9997 +#define UDF_FLAG_STRICT                                5
9998 +#define UDF_FLAG_UNDELETE                      6
9999 +#define UDF_FLAG_UNHIDE                                7
10000 +#define UDF_FLAG_VARCONV                       8
10001 +
10002 +#define UDF_PART_FLAG_UNALLOC_BITMAP           0x0001
10003 +#define UDF_PART_FLAG_UNALLOC_TABLE                    0x0002
10004 +#define UDF_PART_FLAG_FREED_BITMAP                     0x0004
10005 +#define UDF_PART_FLAG_FREED_TABLE                      0x0008
10006 +
10007 +/* following is set only when compiling outside kernel tree */
10008 +#ifndef CONFIG_UDF_FS_EXT
10009 +
10010 +#define UDF_SB_ALLOC(X)
10011 +#define UDF_SB_FREE(X)\
10012 +{\
10013 +       if (UDF_SB(X))\
10014 +       {\
10015 +               if (UDF_SB_PARTMAPS(X))\
10016 +                       kfree(UDF_SB_PARTMAPS(X));\
10017 +               UDF_SB_PARTMAPS(X) = NULL;\
10018 +       }\
10019 +}
10020 +#define UDF_SB(X)      (&((X)->u.udf_sb))
10021 +
10022 +#else
10023 +       /* else we kmalloc a page to hold our stuff */
10024 +#define UDF_SB_ALLOC(X)\
10025 +       (UDF_SB(X) = kmalloc(sizeof(struct udf_sb_info), GFP_KERNEL))
10026 +#define UDF_SB_FREE(X)\
10027 +{\
10028 +       if (UDF_SB(X))\
10029 +       {\
10030 +               if (UDF_SB_PARTMAPS(X))\
10031 +                       kfree(UDF_SB_PARTMAPS(X));\
10032 +               kfree(UDF_SB(X));\
10033 +               UDF_SB(X) = NULL;\
10034 +       }\
10035 +}
10036 +
10037 +#define UDF_SB(X)      ((struct udf_sb_info *) ((X)->u.generic_sbp))
10038 +#endif
10039 +
10040 +#define UDF_SB_ALLOC_PARTMAPS(X,Y)\
10041 +{\
10042 +       UDF_SB_NUMPARTS(X) = Y;\
10043 +       UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\
10044 +       memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
10045 +}
10046 +
10047 +#define UDF_SB_ALLOC_BITMAP(X,Y,Z)\
10048 +{\
10049 +       int nr_groups = ((UDF_SB_PARTLEN((X),(Y)) + (sizeof(struct SpaceBitmapDesc) << 3) +\
10050 +               ((X)->s_blocksize * 8) - 1) / ((X)->s_blocksize * 8));\
10051 +       UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = kmalloc(sizeof(struct udf_bitmap) +\
10052 +               sizeof(struct buffer_head *) * nr_groups,\
10053 +               GFP_KERNEL);\
10054 +       memset(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap, 0x00,\
10055 +               sizeof(struct udf_bitmap) + sizeof(struct buffer_head *) * nr_groups);\
10056 +       UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap =\
10057 +               (struct buffer_head **)(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap + 1);\
10058 +       UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups = nr_groups;\
10059 +}
10060 +
10061 +
10062 +#define UDF_QUERY_FLAG(X,Y)                            ( UDF_SB(X)->s_flags & ( 1 << (Y) ) )
10063 +#define UDF_SET_FLAG(X,Y)                              ( UDF_SB(X)->s_flags |= ( 1 << (Y) ) )
10064 +#define UDF_CLEAR_FLAG(X,Y)                            ( UDF_SB(X)->s_flags &= ~( 1 << (Y) ) )
10065 +
10066 +#define UDF_UPDATE_UDFREV(X,Y)                 ( ((Y) > UDF_SB_UDFREV(X)) ? UDF_SB_UDFREV(X) = (Y) : UDF_SB_UDFREV(X) )
10067 +
10068 +#define UDF_SB_PARTMAPS(X)                             ( UDF_SB(X)->s_partmaps )
10069 +#define UDF_SB_PARTTYPE(X,Y)                   ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_type )
10070 +#define UDF_SB_PARTROOT(X,Y)                   ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_root )
10071 +#define UDF_SB_PARTLEN(X,Y)                            ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_len )
10072 +#define UDF_SB_PARTVSN(X,Y)                            ( UDF_SB_PARTMAPS(X)[(Y)].s_volumeseqnum )
10073 +#define UDF_SB_PARTNUM(X,Y)                            ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_num )
10074 +#define UDF_SB_TYPESPAR(X,Y)                   ( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_sparing )
10075 +#define UDF_SB_TYPEVIRT(X,Y)                   ( UDF_SB_PARTMAPS(X)[(Y)].s_type_specific.s_virtual )
10076 +#define UDF_SB_PARTFUNC(X,Y)                   ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_func )
10077 +#define UDF_SB_PARTFLAGS(X,Y)                  ( UDF_SB_PARTMAPS(X)[(Y)].s_partition_flags )
10078 +#define UDF_SB_BITMAP(X,Y,Z,I)                 ( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap[I] )
10079 +#define UDF_SB_BITMAP_NR_GROUPS(X,Y,Z) ( UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups )
10080 +
10081 +#define UDF_SB_VOLIDENT(X)                             ( UDF_SB(X)->s_volident )
10082 +#define UDF_SB_NUMPARTS(X)                             ( UDF_SB(X)->s_partitions )
10083 +#define UDF_SB_PARTITION(X)                            ( UDF_SB(X)->s_partition )
10084 +#define UDF_SB_SESSION(X)                              ( UDF_SB(X)->s_session )
10085 +#define UDF_SB_ANCHOR(X)                               ( UDF_SB(X)->s_anchor )
10086 +#define UDF_SB_LASTBLOCK(X)                            ( UDF_SB(X)->s_lastblock )
10087 +#define UDF_SB_LVIDBH(X)                               ( UDF_SB(X)->s_lvidbh )
10088 +#define UDF_SB_LVID(X)                                 ( (struct LogicalVolIntegrityDesc *)UDF_SB_LVIDBH(X)->b_data )
10089 +#define UDF_SB_LVIDIU(X)                               ( (struct LogicalVolIntegrityDescImpUse *)&(UDF_SB_LVID(X)->impUse[UDF_SB_LVID(X)->numOfPartitions * 2 * sizeof(Uint32)/sizeof(Uint8)]) )
10090 +
10091 +#define UDF_SB_UMASK(X)                                        ( UDF_SB(X)->s_umask )
10092 +#define UDF_SB_GID(X)                                  ( UDF_SB(X)->s_gid )
10093 +#define UDF_SB_UID(X)                                  ( UDF_SB(X)->s_uid )
10094 +#define UDF_SB_RECORDTIME(X)                   ( UDF_SB(X)->s_recordtime )
10095 +#define UDF_SB_SERIALNUM(X)                            ( UDF_SB(X)->s_serialnum )
10096 +#define UDF_SB_UDFREV(X)                               ( UDF_SB(X)->s_udfrev )
10097 +#define UDF_SB_FLAGS(X)                                        ( UDF_SB(X)->s_flags )
10098 +#define UDF_SB_VAT(X)                                  ( UDF_SB(X)->s_vat )
10099 +
10100 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,6)
10101 +#define UDF_SB_RENAME_LOCK(X)                  ( UDF_SB(X)->s_rename_lock )
10102 +#define UDF_SB_RENAME_WAIT(X)                  ( UDF_SB(X)->s_rename_wait )
10103 +#endif
10104 +
10105 +#endif /* __LINUX_UDF_SB_H */
10106 diff -Nru linux/fs/udf/udfdecl.h linux.new/fs/udf/udfdecl.h
10107 --- linux/fs/udf/udfdecl.h      Thu Jan  1 01:00:00 1970
10108 +++ linux.new/fs/udf/udfdecl.h  Fri Sep  7 11:32:16 2001
10109 @@ -0,0 +1,244 @@
10110 +#ifndef __UDF_DECL_H
10111 +#define __UDF_DECL_H
10112 +
10113 +#include <linux/udf_167.h>
10114 +#include <linux/udf_udf.h>
10115 +#include "udfend.h"
10116 +
10117 +#include <linux/udf_fs.h>
10118 +
10119 +#ifdef __KERNEL__
10120 +
10121 +#include <linux/config.h>
10122 +#include <linux/fs.h>
10123 +#include <linux/types.h>
10124 +
10125 +#ifndef LINUX_VERSION_CODE
10126 +#include <linux/version.h>
10127 +#endif
10128 +
10129 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,70)
10130 +#error "The UDF Module Current Requires Kernel Version 2.1.70 or greater"
10131 +#endif
10132 +
10133 +#if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE)
10134 +#define CONFIG_UDF_FS_MODULE
10135 +#include <linux/udf_fs_sb.h>
10136 +#include <linux/udf_fs_i.h>
10137 +#endif
10138 +
10139 +#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
10140 +#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
10141 +
10142 +#define CURRENT_UTIME  (xtime.tv_usec)
10143 +
10144 +#define udf_file_entry_alloc_offset(inode)\
10145 +       ((UDF_I_EXTENDED_FE(inode) ?\
10146 +               sizeof(struct ExtendedFileEntry) :\
10147 +               sizeof(struct FileEntry)) + UDF_I_LENEATTR(inode))
10148 +
10149 +#define udf_ext0_offset(inode)\
10150 +       (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB ?\
10151 +               udf_file_entry_alloc_offset(inode) : 0)
10152 +
10153 +#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
10154 +
10155 +#else
10156 +
10157 +#include <sys/types.h>
10158 +
10159 +#endif /* __KERNEL__ */
10160 +
10161 +
10162 +
10163 +#ifdef __KERNEL__
10164 +
10165 +struct dentry;
10166 +struct inode;
10167 +struct task_struct;
10168 +struct buffer_head;
10169 +struct super_block;
10170 +
10171 +extern struct inode_operations udf_dir_inode_operations;
10172 +extern struct inode_operations udf_file_inode_operations;
10173 +extern struct inode_operations udf_file_inode_operations_adinicb;
10174 +extern struct inode_operations udf_symlink_inode_operations;
10175 +
10176 +struct udf_fileident_bh
10177 +{
10178 +       struct buffer_head *sbh;
10179 +       struct buffer_head *ebh;
10180 +       int soffset;
10181 +       int eoffset;
10182 +};
10183 +
10184 +#endif /* __KERNEL__ */
10185 +
10186 +struct udf_directory_record
10187 +{
10188 +       Uint32  d_parent;
10189 +       Uint32  d_inode;
10190 +       Uint32  d_name[255];
10191 +};
10192 +
10193 +
10194 +struct udf_vds_record
10195 +{
10196 +       Uint32 block;
10197 +       Uint32 volDescSeqNum;
10198 +};
10199 +
10200 +struct ktm
10201 +{
10202 +       int tm_sec;
10203 +       int tm_min;
10204 +       int tm_hour;
10205 +       int tm_mday;
10206 +       int tm_mon;
10207 +       int tm_year;
10208 +       int tm_isdst;
10209 +};
10210 +
10211 +struct ustr
10212 +{
10213 +       Uint8 u_cmpID;
10214 +       Uint8 u_name[UDF_NAME_LEN];
10215 +       Uint8 u_len;
10216 +       Uint8 padding;
10217 +       unsigned long u_hash;
10218 +};
10219 +
10220 +#ifdef __KERNEL__
10221 +
10222 +/* super.c */
10223 +extern void udf_error(struct super_block *, const char *, const char *, ...);
10224 +extern void udf_warning(struct super_block *, const char *, const char *, ...);
10225 +
10226 +/* namei.c */
10227 +extern int udf_write_fi(struct FileIdentDesc *, struct FileIdentDesc *, struct udf_fileident_bh *, Uint8 *, Uint8 *);
10228 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,7)
10229 +extern int udf_lookup(struct inode *, struct dentry *);
10230 +#else
10231 +extern struct dentry * udf_lookup(struct inode *, struct dentry *);
10232 +#endif
10233 +extern int udf_create(struct inode *, struct dentry *, int);
10234 +extern int udf_mknod(struct inode *, struct dentry *, int, int);
10235 +extern int udf_mkdir(struct inode *, struct dentry *, int);
10236 +extern int udf_rmdir(struct inode *, struct dentry *);
10237 +extern int udf_unlink(struct inode *, struct dentry *);
10238 +extern int udf_symlink(struct inode *, struct dentry *, const char *);
10239 +extern int udf_link(struct dentry *, struct inode *, struct dentry *);
10240 +extern int udf_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
10241 +
10242 +/* file.c */
10243 +extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
10244 +
10245 +/* inode.c */
10246 +extern struct inode *udf_iget(struct super_block *, lb_addr);
10247 +extern int udf_sync_inode(struct inode *);
10248 +extern void udf_expand_file_adinicb(struct inode *, int, int *);
10249 +extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *);
10250 +extern struct buffer_head * udf_getblk(struct inode *, long, int, int *);
10251 +extern struct buffer_head * udf_bread(struct inode *, int, int, int *);
10252 +extern void udf_read_inode(struct inode *);
10253 +extern void udf_put_inode(struct inode *);
10254 +extern void udf_delete_inode(struct inode *);
10255 +extern void udf_write_inode(struct inode *);
10256 +extern int inode_bmap(struct inode *, int, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
10257 +extern int udf_bmap(struct inode *, int);
10258 +extern int udf_readpage_adinicb(struct file *, struct page *);
10259 +extern int udf_add_aext(struct inode *, lb_addr *, int *, lb_addr, Uint32, struct buffer_head **, int);
10260 +extern int udf_write_aext(struct inode *, lb_addr, int *, lb_addr, Uint32, struct buffer_head *, int);
10261 +extern int udf_insert_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
10262 +extern int udf_delete_aext(struct inode *, lb_addr, int, lb_addr, Uint32, struct buffer_head *);
10263 +extern int udf_next_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
10264 +extern int udf_current_aext(struct inode *, lb_addr *, int *, lb_addr *, Uint32 *, struct buffer_head **, int);
10265 +extern void udf_discard_prealloc(struct inode *);
10266 +
10267 +/* misc.c */
10268 +extern int udf_read_tagged_data(char *, int size, int fd, int block, int partref);
10269 +extern struct buffer_head *udf_tread(struct super_block *, int, int);
10270 +extern struct GenericAttrFormat *udf_add_extendedattr(struct inode *, Uint32, Uint32, Uint8, struct buffer_head **);
10271 +extern struct GenericAttrFormat *udf_get_extendedattr(struct inode *, Uint32, Uint8, struct buffer_head **);
10272 +extern struct buffer_head *udf_read_tagged(struct super_block *, Uint32, Uint32, Uint16 *);
10273 +extern struct buffer_head *udf_read_ptagged(struct super_block *, lb_addr, Uint32, Uint16 *);
10274 +extern struct buffer_head *udf_read_untagged(struct super_block *, Uint32, Uint32);
10275 +extern void udf_release_data(struct buffer_head *);
10276 +
10277 +/* lowlevel.c */
10278 +extern unsigned int udf_get_last_session(struct super_block *);
10279 +extern unsigned int udf_get_last_block(struct super_block *);
10280 +
10281 +/* partition.c */
10282 +extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32);
10283 +extern Uint32 udf_get_pblock_virt15(struct super_block *, Uint32, Uint16, Uint32);
10284 +extern Uint32 udf_get_pblock_virt20(struct super_block *, Uint32, Uint16, Uint32);
10285 +extern Uint32 udf_get_pblock_spar15(struct super_block *, Uint32, Uint16, Uint32);
10286 +extern void udf_fill_spartable(struct super_block *, struct udf_sparing_data *, int);
10287 +
10288 +/* unicode.c */
10289 +extern int udf_get_filename(Uint8 *, Uint8 *, int);
10290 +
10291 +/* ialloc.c */
10292 +extern void udf_free_inode(struct inode *);
10293 +extern struct inode * udf_new_inode (const struct inode *, int, int *);
10294 +
10295 +/* truncate.c */
10296 +extern void udf_trunc(struct inode *);
10297 +extern void udf_truncate(struct inode *);
10298 +extern void udf_truncate_adinicb(struct inode *);
10299 +
10300 +/* balloc.c */
10301 +extern inline void udf_free_blocks(const struct inode *, lb_addr, Uint32, Uint32);
10302 +extern inline int udf_prealloc_blocks(const struct inode *, Uint16, Uint32, Uint32);
10303 +extern inline int udf_new_block(const struct inode *, Uint16, Uint32, int *);
10304 +
10305 +/* fsync.c */
10306 +extern int udf_sync_file(struct file *, struct dentry *);
10307 +extern int udf_sync_file_adinicb(struct file *, struct dentry *);
10308 +
10309 +/* directory.c */
10310 +extern Uint8 * udf_filead_read(struct inode *, Uint8 *, Uint8, lb_addr, int *, int *, struct buffer_head **, int *);
10311 +extern struct FileIdentDesc * udf_fileident_read(struct inode *, int *, struct udf_fileident_bh *, struct FileIdentDesc *, lb_addr *, Uint32 *, lb_addr *, Uint32 *, Uint32 *, struct buffer_head **);
10312 +
10313 +#endif /* __KERNEL__ */
10314 +
10315 +/* Miscellaneous UDF Prototypes */
10316 +
10317 +/* unicode.c */
10318 +extern int udf_ustr_to_dchars(Uint8 *, const struct ustr *, int);
10319 +extern int udf_ustr_to_char(Uint8 *, const struct ustr *, int);
10320 +extern int udf_ustr_to_dstring(dstring *, const struct ustr *, int);
10321 +extern int udf_dchars_to_ustr(struct ustr *, const Uint8 *, int);
10322 +extern int udf_char_to_ustr(struct ustr *, const Uint8 *, int);
10323 +extern int udf_dstring_to_ustr(struct ustr *, const dstring *, int);
10324 +extern int udf_translate_to_linux(Uint8 *, Uint8 *, int, Uint8 *, int);
10325 +extern int udf_build_ustr(struct ustr *, dstring *, int);
10326 +extern int udf_build_ustr_exact(struct ustr *, dstring *, int);
10327 +extern int udf_CS0toUTF8(struct ustr *, struct ustr *);
10328 +extern int udf_UTF8toCS0(dstring *, struct ustr *, int);
10329 +
10330 +/* crc.c */
10331 +extern Uint16 udf_crc(Uint8 *, Uint32, Uint16);
10332 +
10333 +/* misc.c */
10334 +extern uid_t  udf_convert_uid(int);
10335 +extern gid_t  udf_convert_gid(int);
10336 +extern Uint32 udf64_low32(Uint64);
10337 +extern Uint32 udf64_high32(Uint64);
10338 +extern void udf_update_tag(char *, int);
10339 +extern void udf_new_tag(char *, Uint16, Uint16, Uint16, Uint32, int);
10340 +
10341 +/* udftime.c */
10342 +extern time_t *udf_stamp_to_time(time_t *, long *, timestamp);
10343 +extern timestamp *udf_time_to_stamp(timestamp *, time_t, long);
10344 +extern time_t udf_converttime (struct ktm *);
10345 +
10346 +/* directory.c */
10347 +extern struct FileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
10348 +extern extent_ad * udf_get_fileextent(void * buffer, int bufsize, int * offset);
10349 +extern long_ad * udf_get_filelongad(void * buffer, int bufsize, int * offset, int);
10350 +extern short_ad * udf_get_fileshortad(void * buffer, int bufsize, int * offset, int);
10351 +extern Uint8 * udf_get_filead(struct FileEntry *, Uint8 *, int, int, int, int *);
10352 +
10353 +#endif /* __UDF_DECL_H */
10354 diff -Nru linux/fs/udf/udfend.h linux.new/fs/udf/udfend.h
10355 --- linux/fs/udf/udfend.h       Thu Jan  1 01:00:00 1970
10356 +++ linux.new/fs/udf/udfend.h   Fri Sep  7 11:32:16 2001
10357 @@ -0,0 +1,132 @@
10358 +#ifndef __UDF_ENDIAN_H
10359 +#define __UDF_ENDIAN_H
10360 +
10361 +#ifndef __KERNEL__ 
10362 +
10363 +#include <sys/types.h>
10364 +
10365 +#if __BYTE_ORDER == 0
10366 +
10367 +#error "__BYTE_ORDER must be defined"
10368 +
10369 +#elif __BYTE_ORDER == __BIG_ENDIAN
10370 +
10371 +#define le16_to_cpu(x) \
10372 +       ((Uint16)((((Uint16)(x) & 0x00FFU) << 8) | \
10373 +                 (((Uint16)(x) & 0xFF00U) >> 8)))
10374
10375 +#define le32_to_cpu(x) \
10376 +       ((Uint32)((((Uint32)(x) & 0x000000FFU) << 24) | \
10377 +                 (((Uint32)(x) & 0x0000FF00U) <<  8) | \
10378 +                 (((Uint32)(x) & 0x00FF0000U) >>  8) | \
10379 +                 (((Uint32)(x) & 0xFF000000U) >> 24)))
10380 +
10381 +#define le64_to_cpu(x) \
10382 +       ((Uint64)((((Uint64)(x) & 0x00000000000000FFULL) << 56) | \
10383 +                 (((Uint64)(x) & 0x000000000000FF00ULL) << 40) | \
10384 +                 (((Uint64)(x) & 0x0000000000FF0000ULL) << 24) | \
10385 +                 (((Uint64)(x) & 0x00000000FF000000ULL) <<  8) | \
10386 +                 (((Uint64)(x) & 0x000000FF00000000ULL) >>  8) | \
10387 +                 (((Uint64)(x) & 0x0000FF0000000000ULL) >> 24) | \
10388 +                 (((Uint64)(x) & 0x00FF000000000000ULL) >> 40) | \
10389 +                 (((Uint64)(x) & 0xFF00000000000000ULL) >> 56)))               
10390 +
10391 +#define cpu_to_le16(x) (le16_to_cpu(x))
10392 +#define cpu_to_le32(x) (le32_to_cpu(x))
10393 +#define cpu_to_le64(x) (le64_to_cpu(x))
10394 +
10395 +#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
10396 +
10397 +#define le16_to_cpu(x) (x)
10398 +#define le32_to_cpu(x) (x)
10399 +#define le64_to_cpu(x) (x)
10400 +#define cpu_to_le16(x) (x)
10401 +#define cpu_to_le32(x) (x)
10402 +#define cpu_to_le64(x) (x)
10403 +
10404 +#endif /* __BYTE_ORDER == 0 */
10405 +
10406 +#include <string.h>
10407 +
10408 +#else /* __KERNEL__ */
10409 +
10410 +#include <asm/byteorder.h>
10411 +#include <linux/string.h>
10412 +
10413 +#endif /* ! __KERNEL__ */
10414 +
10415 +static inline lb_addr lelb_to_cpu(lb_addr in)
10416 +{
10417 +       lb_addr out;
10418 +       out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
10419 +       out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
10420 +       return out;
10421 +}
10422 +
10423 +static inline lb_addr cpu_to_lelb(lb_addr in)
10424 +{
10425 +       lb_addr out;
10426 +       out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
10427 +       out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
10428 +       return out;
10429 +}
10430 +
10431 +static inline timestamp lets_to_cpu(timestamp in)
10432 +{
10433 +       timestamp out;
10434 +       memcpy(&out, &in, sizeof(timestamp));
10435 +       out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone);
10436 +       out.year = le16_to_cpu(in.year);
10437 +       return out;
10438 +}
10439 +
10440 +static inline short_ad lesa_to_cpu(short_ad in)
10441 +{
10442 +       short_ad out;
10443 +       out.extLength = le32_to_cpu(in.extLength);
10444 +       out.extPosition = le32_to_cpu(in.extPosition);
10445 +       return out;
10446 +}
10447 +
10448 +static inline short_ad cpu_to_lesa(short_ad in)
10449 +{
10450 +       short_ad out;
10451 +       out.extLength = cpu_to_le32(in.extLength);
10452 +       out.extPosition = cpu_to_le32(in.extPosition);
10453 +       return out;
10454 +}
10455 +
10456 +static inline long_ad lela_to_cpu(long_ad in)
10457 +{
10458 +       long_ad out;
10459 +       out.extLength = le32_to_cpu(in.extLength);
10460 +       out.extLocation = lelb_to_cpu(in.extLocation);
10461 +       return out;
10462 +}
10463 +
10464 +static inline long_ad cpu_to_lela(long_ad in)
10465 +{
10466 +       long_ad out;
10467 +       out.extLength = cpu_to_le32(in.extLength);
10468 +       out.extLocation = cpu_to_lelb(in.extLocation);
10469 +       return out;
10470 +}
10471 +
10472 +static inline extent_ad leea_to_cpu(extent_ad in)
10473 +{
10474 +       extent_ad out;
10475 +       out.extLength = le32_to_cpu(in.extLength);
10476 +       out.extLocation = le32_to_cpu(in.extLocation);
10477 +       return out;
10478 +}
10479 +
10480 +static inline timestamp cpu_to_lets(timestamp in)
10481 +{
10482 +       timestamp out;
10483 +       memcpy(&out, &in, sizeof(timestamp));
10484 +       out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone);
10485 +       out.year = cpu_to_le16(in.year);
10486 +       return out;
10487 +}
10488 +
10489 +#endif /* __UDF_ENDIAN_H */
10490 diff -Nru linux/fs/udf/udftime.c linux.new/fs/udf/udftime.c
10491 --- linux/fs/udf/udftime.c      Thu Jan  1 01:00:00 1970
10492 +++ linux.new/fs/udf/udftime.c  Fri Sep  7 11:32:16 2001
10493 @@ -0,0 +1,186 @@
10494 +/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
10495 +   This file is part of the GNU C Library.
10496 +   Contributed by Paul Eggert (eggert@twinsun.com).
10497 +
10498 +   The GNU C Library is free software; you can redistribute it and/or
10499 +   modify it under the terms of the GNU Library General Public License as
10500 +   published by the Free Software Foundation; either version 2 of the
10501 +   License, or (at your option) any later version.
10502 +
10503 +   The GNU C Library is distributed in the hope that it will be useful,
10504 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
10505 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10506 +   Library General Public License for more details.
10507 +
10508 +   You should have received a copy of the GNU Library General Public
10509 +   License along with the GNU C Library; see the file COPYING.LIB.  If not,
10510 +   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
10511 +   Boston, MA 02111-1307, USA.  */
10512 +
10513 +/*
10514 + * dgb 10/02/98: ripped this from glibc source to help convert timestamps to unix time 
10515 + *     10/04/98: added new table-based lookup after seeing how ugly the gnu code is
10516 + * blf 09/27/99: ripped out all the old code and inserted new table from
10517 + *                                     John Brockmeyer (without leap second corrections)
10518 + *                              rewrote udf_stamp_to_time and fixed timezone accounting in
10519 +                                       udf_time_to_stamp.
10520 + */
10521 +
10522 +/*
10523 + * We don't take into account leap seconds. This may be correct or incorrect.
10524 + * For more NIST information (especially dealing with leap seconds), see:
10525 + *  http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
10526 + */
10527 +
10528 +#if defined(__linux__) && defined(__KERNEL__)
10529 +#include <linux/types.h>
10530 +#include <linux/kernel.h>
10531 +#else
10532 +#include <stdio.h>
10533 +#include <sys/types.h>
10534 +#include <sys/time.h>
10535 +#endif
10536 +
10537 +#include "udfdecl.h"
10538 +
10539 +#define EPOCH_YEAR 1970
10540 +
10541 +#ifndef __isleap
10542 +/* Nonzero if YEAR is a leap year (every 4 years,
10543 +   except every 100th isn't, and every 400th is).  */
10544 +#define        __isleap(year)  \
10545 +  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
10546 +#endif
10547 +
10548 +/* How many days come before each month (0-12).  */
10549 +const unsigned short int __mon_yday[2][13] =
10550 +{
10551 +       /* Normal years.  */
10552 +       { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
10553 +       /* Leap years.  */
10554 +       { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
10555 +};
10556 +
10557 +#define MAX_YEAR_SECONDS       69
10558 +#define SPD 0x15180 /*3600*24*/
10559 +#define SPY(y,l,s) (SPD * (365*y+l)+s)
10560 +
10561 +time_t year_seconds[MAX_YEAR_SECONDS]= {
10562 +/*1970*/ SPY( 0, 0,0), SPY( 1, 0,0), SPY( 2, 0,0), SPY( 3, 1,0), 
10563 +/*1974*/ SPY( 4, 1,0), SPY( 5, 1,0), SPY( 6, 1,0), SPY( 7, 2,0), 
10564 +/*1978*/ SPY( 8, 2,0), SPY( 9, 2,0), SPY(10, 2,0), SPY(11, 3,0), 
10565 +/*1982*/ SPY(12, 3,0), SPY(13, 3,0), SPY(14, 3,0), SPY(15, 4,0), 
10566 +/*1986*/ SPY(16, 4,0), SPY(17, 4,0), SPY(18, 4,0), SPY(19, 5,0), 
10567 +/*1990*/ SPY(20, 5,0), SPY(21, 5,0), SPY(22, 5,0), SPY(23, 6,0), 
10568 +/*1994*/ SPY(24, 6,0), SPY(25, 6,0), SPY(26, 6,0), SPY(27, 7,0), 
10569 +/*1998*/ SPY(28, 7,0), SPY(29, 7,0), SPY(30, 7,0), SPY(31, 8,0), 
10570 +/*2002*/ SPY(32, 8,0), SPY(33, 8,0), SPY(34, 8,0), SPY(35, 9,0), 
10571 +/*2006*/ SPY(36, 9,0), SPY(37, 9,0), SPY(38, 9,0), SPY(39,10,0), 
10572 +/*2010*/ SPY(40,10,0), SPY(41,10,0), SPY(42,10,0), SPY(43,11,0), 
10573 +/*2014*/ SPY(44,11,0), SPY(45,11,0), SPY(46,11,0), SPY(47,12,0), 
10574 +/*2018*/ SPY(48,12,0), SPY(49,12,0), SPY(50,12,0), SPY(51,13,0), 
10575 +/*2022*/ SPY(52,13,0), SPY(53,13,0), SPY(54,13,0), SPY(55,14,0), 
10576 +/*2026*/ SPY(56,14,0), SPY(57,14,0), SPY(58,14,0), SPY(59,15,0), 
10577 +/*2030*/ SPY(60,15,0), SPY(61,15,0), SPY(62,15,0), SPY(63,16,0), 
10578 +/*2034*/ SPY(64,16,0), SPY(65,16,0), SPY(66,16,0), SPY(67,17,0), 
10579 +/*2038*/ SPY(68,17,0)
10580 +};
10581 +
10582 +#ifdef __KERNEL__
10583 +extern struct timezone sys_tz;
10584 +#endif
10585 +
10586 +#define SECS_PER_HOUR  (60 * 60)
10587 +#define SECS_PER_DAY   (SECS_PER_HOUR * 24)
10588 +
10589 +time_t *
10590 +udf_stamp_to_time(time_t *dest, long *dest_usec, timestamp src)
10591 +{
10592 +       int yday;
10593 +       Uint8 type = src.typeAndTimezone >> 12;
10594 +       Sint16 offset;
10595 +
10596 +       if (type == 1)
10597 +       {
10598 +               offset = src.typeAndTimezone << 4;
10599 +               /* sign extent offset */
10600 +               offset = (offset >> 4);
10601 +       }
10602 +       else
10603 +               offset = 0;
10604 +
10605 +       if ((src.year < EPOCH_YEAR) ||
10606 +               (src.year > EPOCH_YEAR+MAX_YEAR_SECONDS))
10607 +       {
10608 +               *dest = -1;
10609 +               *dest_usec = -1;
10610 +               return NULL;
10611 +       }
10612 +       *dest = year_seconds[src.year - EPOCH_YEAR];
10613 +       *dest -= offset * 60;
10614 +
10615 +       yday = ((__mon_yday[__isleap (src.year)]
10616 +               [src.month-1]) + (src.day-1));
10617 +       *dest += ( ( (yday* 24) + src.hour ) * 60 + src.minute ) * 60 + src.second;
10618 +       *dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds;
10619 +       return dest;
10620 +}
10621 +
10622 +
10623 +timestamp *
10624 +udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec)
10625 +{
10626 +       long int days, rem, y;
10627 +       const unsigned short int *ip;
10628 +       Sint16 offset;
10629 +#ifndef __KERNEL__
10630 +       struct timeval tv;
10631 +       struct timezone sys_tz;
10632 +
10633 +       gettimeofday(&tv, &sys_tz);
10634 +#endif
10635 +       offset = -sys_tz.tz_minuteswest;
10636 +
10637 +       if (!dest)
10638 +               return NULL;
10639 +
10640 +       dest->typeAndTimezone = 0x1000 | (offset & 0x0FFF);
10641 +
10642 +       tv_sec += offset * 60;
10643 +       days = tv_sec / SECS_PER_DAY;
10644 +       rem = tv_sec % SECS_PER_DAY;
10645 +       dest->hour = rem / SECS_PER_HOUR;
10646 +       rem %= SECS_PER_HOUR;
10647 +       dest->minute = rem / 60;
10648 +       dest->second = rem % 60;
10649 +       y = 1970;
10650 +
10651 +#define DIV(a,b) ((a) / (b) - ((a) % (b) < 0))
10652 +#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
10653 +
10654 +       while (days < 0 || days >= (__isleap(y) ? 366 : 365))
10655 +       {
10656 +               long int yg = y + days / 365 - (days % 365 < 0);
10657 +
10658 +               /* Adjust DAYS and Y to match the guessed year.  */
10659 +               days -= ((yg - y) * 365
10660 +                       + LEAPS_THRU_END_OF (yg - 1)
10661 +                       - LEAPS_THRU_END_OF (y - 1));
10662 +               y = yg;
10663 +       }
10664 +       dest->year = y;
10665 +       ip = __mon_yday[__isleap(y)];
10666 +       for (y = 11; days < (long int) ip[y]; --y)
10667 +               continue;
10668 +       days -= ip[y];
10669 +       dest->month = y + 1;
10670 +       dest->day = days + 1;
10671 +
10672 +       dest->centiseconds = tv_usec / 10000;
10673 +       dest->hundredsOfMicroseconds = (tv_usec - dest->centiseconds * 10000) / 100;
10674 +       dest->microseconds = (tv_usec - dest->centiseconds * 10000 -
10675 +               dest->hundredsOfMicroseconds * 100);
10676 +       return dest;
10677 +}
10678 +
10679 +/* EOF */
10680 diff -Nru linux/fs/udf/unicode.c linux.new/fs/udf/unicode.c
10681 --- linux/fs/udf/unicode.c      Thu Jan  1 01:00:00 1970
10682 +++ linux.new/fs/udf/unicode.c  Fri Sep  7 11:32:16 2001
10683 @@ -0,0 +1,452 @@
10684 +/*
10685 + * unicode.c
10686 + *
10687 + * PURPOSE
10688 + *     Routines for converting between UTF-8 and OSTA Compressed Unicode.
10689 + *      Also handles filename mangling
10690 + *
10691 + * DESCRIPTION
10692 + *     OSTA Compressed Unicode is explained in the OSTA UDF specification.
10693 + *             http://www.osta.org/
10694 + *     UTF-8 is explained in the IETF RFC XXXX.
10695 + *             ftp://ftp.internic.net/rfc/rfcxxxx.txt
10696 + *
10697 + * CONTACTS
10698 + *     E-mail regarding any portion of the Linux UDF file system should be
10699 + *     directed to the development team's mailing list (run by majordomo):
10700 + *             linux_udf@hootie.lvld.hp.com
10701 + *
10702 + * COPYRIGHT
10703 + *     This file is distributed under the terms of the GNU General Public
10704 + *     License (GPL). Copies of the GPL can be obtained from:
10705 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
10706 + *     Each contributing author retains all rights to their own work.
10707 + */
10708 +
10709 +
10710 +#ifdef __KERNEL__
10711 +#include <linux/kernel.h>
10712 +#include <linux/string.h>      /* for memset */
10713 +#include <linux/udf_fs.h>
10714 +#else
10715 +#include <string.h>
10716 +#endif
10717 +
10718 +#include "udfdecl.h"
10719 +
10720 +int udf_ustr_to_dchars(Uint8 *dest, const struct ustr *src, int strlen)
10721 +{
10722 +       if ( (!dest) || (!src) || (!strlen) || (src->u_len > strlen) )
10723 +               return 0;
10724 +       memcpy(dest+1, src->u_name, src->u_len);
10725 +       dest[0] = src->u_cmpID;
10726 +       return src->u_len + 1;
10727 +}
10728 +
10729 +int udf_ustr_to_char(Uint8 *dest, const struct ustr *src, int strlen)
10730 +{
10731 +       if ( (!dest) || (!src) || (!strlen) || (src->u_len >= strlen) )
10732 +               return 0;
10733 +       memcpy(dest, src->u_name, src->u_len);
10734 +       return src->u_len;
10735 +}
10736 +
10737 +int udf_ustr_to_dstring(dstring *dest, const struct ustr *src, int dlength)
10738 +{
10739 +       if ( udf_ustr_to_dchars(dest, src, dlength-1) )
10740 +       {
10741 +               dest[dlength-1] = src->u_len + 1;
10742 +               return dlength;
10743 +       }
10744 +       else
10745 +               return 0;
10746 +}
10747 +
10748 +int udf_dchars_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
10749 +{
10750 +       if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN) )
10751 +               return 0;
10752 +       memset(dest, 0, sizeof(struct ustr));
10753 +       memcpy(dest->u_name, src+1, strlen-1);
10754 +       dest->u_cmpID = src[0];
10755 +       dest->u_len = strlen-1;
10756 +       return strlen-1;
10757 +}
10758 +
10759 +int udf_char_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
10760 +{
10761 +       if ( (!dest) || (!src) || (!strlen) || (strlen >= UDF_NAME_LEN) )
10762 +               return 0;
10763 +       memset(dest, 0, sizeof(struct ustr));
10764 +       memcpy(dest->u_name, src, strlen);
10765 +       dest->u_cmpID = 0x08;
10766 +       dest->u_len = strlen;
10767 +       return strlen;
10768 +}
10769 +
10770 +
10771 +int udf_dstring_to_ustr(struct ustr *dest, const dstring *src, int dlength)
10772 +{
10773 +       if ( dlength && udf_dchars_to_ustr(dest, src, src[dlength-1]) )
10774 +               return dlength;
10775 +       else
10776 +               return 0;
10777 +}
10778 +
10779 +/*
10780 + * udf_build_ustr
10781 + */
10782 +int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
10783 +{
10784 +       int usesize;
10785 +
10786 +       if ( (!dest) || (!ptr) || (!size) )
10787 +               return -1;
10788 +
10789 +       memset(dest, 0, sizeof(struct ustr));
10790 +       usesize= (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size;
10791 +       dest->u_cmpID=ptr[0];
10792 +       dest->u_len=ptr[size-1];
10793 +       memcpy(dest->u_name, ptr+1, usesize-1);
10794 +       return 0;
10795 +}
10796 +
10797 +/*
10798 + * udf_build_ustr_exact
10799 + */
10800 +int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
10801 +{
10802 +       if ( (!dest) || (!ptr) || (!exactsize) )
10803 +               return -1;
10804 +
10805 +       memset(dest, 0, sizeof(struct ustr));
10806 +       dest->u_cmpID=ptr[0];
10807 +       dest->u_len=exactsize-1;
10808 +       memcpy(dest->u_name, ptr+1, exactsize-1);
10809 +       return 0;
10810 +}
10811 +
10812 +/*
10813 + * udf_ocu_to_udf8
10814 + *
10815 + * PURPOSE
10816 + *     Convert OSTA Compressed Unicode to the UTF-8 equivalent.
10817 + *
10818 + * DESCRIPTION
10819 + *     This routine is only called by udf_filldir().
10820 + *
10821 + * PRE-CONDITIONS
10822 + *     utf                     Pointer to UTF-8 output buffer.
10823 + *     ocu                     Pointer to OSTA Compressed Unicode input buffer
10824 + *                             of size UDF_NAME_LEN bytes.
10825 + *                             both of type "struct ustr *"
10826 + *
10827 + * POST-CONDITIONS
10828 + *     <return>                Zero on success.
10829 + *
10830 + * HISTORY
10831 + *     November 12, 1997 - Andrew E. Mileski
10832 + *     Written, tested, and released.
10833 + */
10834 +int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
10835 +{
10836 +       Uint8 *ocu;
10837 +       Uint32 c;
10838 +       Uint8 cmp_id, ocu_len;
10839 +       int i;
10840 +
10841 +       ocu = ocu_i->u_name;
10842 +
10843 +       ocu_len = ocu_i->u_len;
10844 +       cmp_id = ocu_i->u_cmpID;
10845 +       utf_o->u_len = 0;
10846 +
10847 +       if (ocu_len == 0)
10848 +       {
10849 +               memset(utf_o, 0, sizeof(struct ustr));
10850 +               utf_o->u_cmpID = 0;
10851 +               utf_o->u_len = 0;
10852 +               return 0;
10853 +       }
10854 +
10855 +       if ((cmp_id != 8) && (cmp_id != 16))
10856 +       {
10857 +#ifdef __KERNEL__
10858 +               printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
10859 +#endif
10860 +               return 0;
10861 +       }
10862 +
10863 +       for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
10864 +       {
10865 +
10866 +               /* Expand OSTA compressed Unicode to Unicode */
10867 +               c = ocu[i++];
10868 +               if (cmp_id == 16)
10869 +                       c = (c << 8) | ocu[i++];
10870 +
10871 +               /* Compress Unicode to UTF-8 */
10872 +               if (c < 0x80U)
10873 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)c;
10874 +               else if (c < 0x800U)
10875 +               {
10876 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)(0xc0 | (c >> 6));
10877 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
10878 +               }
10879 +               else
10880 +               {
10881 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)(0xe0 | (c >> 12));
10882 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | ((c >> 6) & 0x3f));
10883 +                       utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
10884 +               }
10885 +       }
10886 +       utf_o->u_cmpID=8;
10887 +       utf_o->u_hash=0L;
10888 +       utf_o->padding=0;
10889 +
10890 +       return utf_o->u_len;
10891 +}
10892 +
10893 +/*
10894 + *
10895 + * udf_utf8_to_ocu
10896 + *
10897 + * PURPOSE
10898 + *     Convert UTF-8 to the OSTA Compressed Unicode equivalent.
10899 + *
10900 + * DESCRIPTION
10901 + *     This routine is only called by udf_lookup().
10902 + *
10903 + * PRE-CONDITIONS
10904 + *     ocu                     Pointer to OSTA Compressed Unicode output
10905 + *                             buffer of size UDF_NAME_LEN bytes.
10906 + *     utf                     Pointer to UTF-8 input buffer.
10907 + *     utf_len                 Length of UTF-8 input buffer in bytes.
10908 + *
10909 + * POST-CONDITIONS
10910 + *     <return>                Zero on success.
10911 + *
10912 + * HISTORY
10913 + *     November 12, 1997 - Andrew E. Mileski
10914 + *     Written, tested, and released.
10915 + */
10916 +int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
10917 +{
10918 +       unsigned c, i, max_val, utf_char;
10919 +       int utf_cnt;
10920 +       int u_len = 0;
10921 +
10922 +       memset(ocu, 0, sizeof(dstring) * length);
10923 +       ocu[0] = 8;
10924 +       max_val = 0xffU;
10925 +
10926 +try_again:
10927 +       utf_char = 0U;
10928 +       utf_cnt = 0U;
10929 +       for (i = 0U; i < utf->u_len; i++)
10930 +       {
10931 +               c = (Uint8)utf->u_name[i];
10932 +
10933 +               /* Complete a multi-byte UTF-8 character */
10934 +               if (utf_cnt)
10935 +               {
10936 +                       utf_char = (utf_char << 6) | (c & 0x3fU);
10937 +                       if (--utf_cnt)
10938 +                               continue;
10939 +               }
10940 +               else
10941 +               {
10942 +                       /* Check for a multi-byte UTF-8 character */
10943 +                       if (c & 0x80U)
10944 +                       {
10945 +                               /* Start a multi-byte UTF-8 character */
10946 +                               if ((c & 0xe0U) == 0xc0U)
10947 +                               {
10948 +                                       utf_char = c & 0x1fU;
10949 +                                       utf_cnt = 1;
10950 +                               }
10951 +                               else if ((c & 0xf0U) == 0xe0U)
10952 +                               {
10953 +                                       utf_char = c & 0x0fU;
10954 +                                       utf_cnt = 2;
10955 +                               }
10956 +                               else if ((c & 0xf8U) == 0xf0U)
10957 +                               {
10958 +                                       utf_char = c & 0x07U;
10959 +                                       utf_cnt = 3;
10960 +                               }
10961 +                               else if ((c & 0xfcU) == 0xf8U)
10962 +                               {
10963 +                                       utf_char = c & 0x03U;
10964 +                                       utf_cnt = 4;
10965 +                               }
10966 +                               else if ((c & 0xfeU) == 0xfcU)
10967 +                               {
10968 +                                       utf_char = c & 0x01U;
10969 +                                       utf_cnt = 5;
10970 +                               }
10971 +                               else
10972 +                                       goto error_out;
10973 +                               continue;
10974 +                       } else
10975 +                               /* Single byte UTF-8 character (most common) */
10976 +                               utf_char = c;
10977 +               }
10978 +
10979 +               /* Choose no compression if necessary */
10980 +               if (utf_char > max_val)
10981 +               {
10982 +                       if ( 0xffU == max_val )
10983 +                       {
10984 +                               max_val = 0xffffU;
10985 +                               ocu[0] = (Uint8)0x10U;
10986 +                               goto try_again;
10987 +                       }
10988 +                       goto error_out;
10989 +               }
10990 +
10991 +               if (max_val == 0xffffU)
10992 +               {
10993 +                       ocu[++u_len] = (Uint8)(utf_char >> 8);
10994 +               }
10995 +               ocu[++u_len] = (Uint8)(utf_char & 0xffU);
10996 +       }
10997 +
10998 +
10999 +       if (utf_cnt)
11000 +       {
11001 +error_out:
11002 +#ifdef __KERNEL__
11003 +               printk(KERN_ERR "udf: bad UTF-8 character\n");
11004 +#endif
11005 +               return 0;
11006 +       }
11007 +
11008 +       ocu[length - 1] = (Uint8)u_len + 1;
11009 +       return u_len + 1;
11010 +}
11011 +
11012 +#ifdef __KERNEL__
11013 +int udf_get_filename(Uint8 *sname, Uint8 *dname, int flen)
11014 +{
11015 +       struct ustr filename, unifilename;
11016 +       int len;
11017 +
11018 +       if (udf_build_ustr_exact(&unifilename, sname, flen))
11019 +       {
11020 +               return 0;
11021 +       }
11022 +
11023 +       if (!udf_CS0toUTF8(&filename, &unifilename) )
11024 +       {
11025 +               udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
11026 +               return 0;
11027 +       }
11028 +
11029 +       if ((len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
11030 +               unifilename.u_name, unifilename.u_len)))
11031 +       {
11032 +               return len;
11033 +       }
11034 +       return 0;
11035 +}
11036 +#endif
11037 +
11038 +#define ILLEGAL_CHAR_MARK      '_'
11039 +#define EXT_MARK                       '.'
11040 +#define CRC_MARK                       '#'
11041 +#define EXT_SIZE                       5
11042 +
11043 +int udf_translate_to_linux(Uint8 *newName, Uint8 *udfName, int udfLen, Uint8 *fidName, int fidNameLen)
11044 +{
11045 +       int index, newIndex = 0, needsCRC = 0;  
11046 +       int extIndex = 0, newExtIndex = 0, hasExt = 0;
11047 +       unsigned short valueCRC;
11048 +       Uint8 curr;
11049 +       const Uint8 hexChar[] = "0123456789ABCDEF";
11050 +
11051 +       if (udfName[0] == '.' && (udfLen == 1 ||
11052 +               (udfLen == 2 && udfName[1] == '.')))
11053 +       {
11054 +               needsCRC = 1;
11055 +               newIndex = udfLen;
11056 +               memcpy(newName, udfName, udfLen);
11057 +       }
11058 +       else
11059 +       {       
11060 +               for (index = 0; index < udfLen; index++)
11061 +               {
11062 +                       curr = udfName[index];
11063 +                       if (curr == '/' || curr == 0)
11064 +                       {
11065 +                               needsCRC = 1;
11066 +                               curr = ILLEGAL_CHAR_MARK;
11067 +                               while (index+1 < udfLen && (udfName[index+1] == '/' ||
11068 +                                       udfName[index+1] == 0))
11069 +                                       index++;
11070 +                       }
11071 +                       if (curr == EXT_MARK && (udfLen - index - 1) <= EXT_SIZE)
11072 +                       {
11073 +                               if (udfLen == index + 1)
11074 +                                       hasExt = 0;
11075 +                               else
11076 +                               {
11077 +                                       hasExt = 1;
11078 +                                       extIndex = index;
11079 +                                       newExtIndex = newIndex;
11080 +                               }
11081 +                       }
11082 +                       if (newIndex < 256)
11083 +                               newName[newIndex++] = curr;
11084 +                       else
11085 +                               needsCRC = 1;
11086 +               }
11087 +       }
11088 +       if (needsCRC)
11089 +       {
11090 +               Uint8 ext[EXT_SIZE];
11091 +               int localExtIndex = 0;
11092 +
11093 +               if (hasExt)
11094 +               {
11095 +                       int maxFilenameLen;
11096 +                       for(index = 0; index<EXT_SIZE && extIndex + index +1 < udfLen;
11097 +                               index++ )
11098 +                       {
11099 +                               curr = udfName[extIndex + index + 1];
11100 +
11101 +                               if (curr == '/' || curr == 0)
11102 +                               {
11103 +                                       needsCRC = 1;
11104 +                                       curr = ILLEGAL_CHAR_MARK;
11105 +                                       while(extIndex + index + 2 < udfLen && (index + 1 < EXT_SIZE
11106 +                                               && (udfName[extIndex + index + 2] == '/' ||
11107 +                                                       udfName[extIndex + index + 2] == 0)))
11108 +                                               index++;
11109 +                               }
11110 +                               ext[localExtIndex++] = curr;
11111 +                       }
11112 +                       maxFilenameLen = 250 - localExtIndex;
11113 +                       if (newIndex > maxFilenameLen)
11114 +                               newIndex = maxFilenameLen;
11115 +                       else
11116 +                               newIndex = newExtIndex;
11117 +               }
11118 +               else if (newIndex > 250)
11119 +                       newIndex = 250;
11120 +               newName[newIndex++] = CRC_MARK;
11121 +               valueCRC = udf_crc(fidName, fidNameLen, 0);
11122 +               newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
11123 +               newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
11124 +               newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
11125 +               newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
11126 +
11127 +               if (hasExt)
11128 +               {
11129 +                       newName[newIndex++] = EXT_MARK;
11130 +                       for (index = 0;index < localExtIndex ;index++ )
11131 +                               newName[newIndex++] = ext[index];
11132 +               }
11133 +       }
11134 +       return newIndex;
11135 +}
11136 diff -Nru linux/include/linux/fs.h linux.new/include/linux/fs.h
11137 --- linux/include/linux/fs.h    Fri Sep  7 11:17:46 2001
11138 +++ linux.new/include/linux/fs.h        Fri Sep  7 11:37:56 2001
11139 @@ -286,6 +286,7 @@
11140  #include <linux/hfs_fs_i.h>
11141  #include <linux/adfs_fs_i.h>
11142  #include <linux/qnx4_fs_i.h>
11143 +#include <linux/udf_fs_i.h>
11144  #include <linux/reiserfs_fs_i.h>
11145  #include <linux/usbdev_fs_i.h>
11146  #include <linux/beos_fs_i.h>
11147 @@ -403,6 +404,7 @@
11148                 struct hfs_inode_info           hfs_i;
11149                 struct adfs_inode_info          adfs_i;
11150                 struct qnx4_inode_info          qnx4_i;
11151 +               struct udf_inode_info           udf_i;
11152                 struct reiserfs_inode_info      reiserfs_i;
11153                 struct usbdev_inode_info        usbdev_i;
11154                 struct socket                   socket_i;
11155 @@ -530,6 +532,7 @@
11156  #include <linux/hfs_fs_sb.h>
11157  #include <linux/adfs_fs_sb.h>
11158  #include <linux/qnx4_fs_sb.h>
11159 +#include <linux/udf_fs_sb.h>
11160  #include <linux/reiserfs_fs_sb.h>
11161  #include <linux/usbdev_fs_sb.h>
11162  #include <linux/beos_fs_sb.h>
11163 @@ -576,7 +579,8 @@
11164                 struct hfs_sb_info      hfs_sb;
11165                 struct adfs_sb_info     adfs_sb;
11166                 struct qnx4_sb_info     qnx4_sb;
11167 -               struct reiserfs_sb_info reiserfs_sb;
11168 +               struct udf_sb_info      udf_sb;
11169 +               struct reiserfs_sb_info reiserfs_sb;
11170                 struct usbdev_sb_info   usbdevfs_sb;
11171                 struct beos_sb_info     beos_sb;
11172                 void                    *generic_sbp;
11173 diff -Nru linux/include/linux/udf_167.h linux.new/include/linux/udf_167.h
11174 --- linux/include/linux/udf_167.h       Thu Jan  1 01:00:00 1970
11175 +++ linux.new/include/linux/udf_167.h   Fri Sep  7 11:32:16 2001
11176 @@ -0,0 +1,786 @@
11177 +#if !defined(_LINUX_UDF_167_H)
11178 +#define _LINUX_UDF_167_H
11179 +/*
11180 + * udf_167.h
11181 + *
11182 + * DESCRIPTION
11183 + *     Definitions from the ECMA 167 standard.
11184 + *     http://www.ecma.ch/
11185 + *
11186 + *     These abbreviations are used to keep the symbols short:
11187 + *             Alloc   Allocation
11188 + *             App     Application
11189 + *             Attr    Attribute
11190 + *             Char    Characters
11191 + *             Desc    Descriptor
11192 + *             Descs   Descriptors
11193 + *             Ext     Extent
11194 + *             Ident   Identifier
11195 + *             Imp     Implementation
11196 + *             Lvl     Level
11197 + *             Max     Maximum
11198 + *             Num     Number
11199 + *             Ptr     Pointer
11200 + *             Seq     Sequence
11201 + *             Std     Standard
11202 + *             Struct  Structure
11203 + *             Vol     Volume
11204 + *     The symbols are otherwise identical to the standard, and the
11205 + *     sections of the standard to refer to are indicated.
11206 + *
11207 + * CONTACTS
11208 + *     E-mail regarding any portion of the Linux UDF file system should be
11209 + *     directed to the development team mailing list (run by majordomo):
11210 + *             linux_udf@hootie.lvld.hp.com
11211 + *
11212 + * COPYRIGHT
11213 + *     This file is distributed under the terms of the GNU General Public
11214 + *     License (GPL). Copies of the GPL can be obtained from:
11215 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
11216 + *     Each contributing author retains all rights to their own work.
11217 + *
11218 + * HISTORY
11219 + *     July 12, 1997 - Andrew E. Mileski
11220 + *     Adapted from the ECMA-167 standard.
11221 + *
11222 + * 10/2/98 dgb Adaptation
11223 + * 10/4/98     Changes by HJA Sandkuyl
11224 + * 10/7/98     Changed FILE_EXISTENCE to FILE_HIDDEN, per UDF 2.0 spec
11225 + * 11/26/98    Modifed some entries for UDF 1.5/2.0
11226 + * 11/26/98 bf  Fixed typos, non-linux types, more structures
11227 + * 12/5/98 dgb  Adjusted structure and content of include files.
11228 + */
11229 +
11230 +#ifdef __KERNEL__
11231 +#include <linux/types.h>
11232 +#define Uint8  __u8
11233 +#define Sint8  __s8
11234 +#define Uint16 __u16
11235 +#define Sint16 __s16
11236 +#define Uint32 __u32
11237 +#define Sint32 __s32
11238 +#define Uint64 __u64
11239 +#define Sint64 __s64
11240 +typedef Uint8  dstring;
11241 +#else
11242 +#define Uint8  unsigned char
11243 +#define Sint8  char
11244 +#define Uint16 unsigned short
11245 +#define Sint16 short
11246 +#define Uint32 unsigned int
11247 +#define Sint32 int
11248 +#define Uint64 unsigned long long
11249 +#define Sint64 long long
11250 +typedef Uint8  dstring;
11251 +#endif
11252 +
11253 +/* make sure all structures are packed! */
11254 +#pragma pack(1)
11255 +
11256 +/* CS0 Charspec (ECMA 167 1/7.2.1) */
11257 +typedef struct {
11258 +       Uint8 charSetType;
11259 +       Uint8 charSetInfo[63];
11260 +} charspec;
11261 +
11262 +/* Timestamp (ECMA 167 1/7.3) */
11263 +typedef struct {
11264 +       Uint16 typeAndTimezone;
11265 +       Uint16 year;
11266 +       Uint8 month;
11267 +       Uint8 day;
11268 +       Uint8 hour;
11269 +       Uint8 minute;
11270 +       Uint8 second;
11271 +       Uint8 centiseconds;
11272 +       Uint8 hundredsOfMicroseconds;
11273 +       Uint8 microseconds;
11274 +} timestamp;
11275 +
11276 +/* Timestamp types (ECMA 167 1/7.3.1) */
11277 +#define TIMESTAMP_TYPE_CUT             0x0000U
11278 +#define TIMESTAMP_TYPE_LOCAL           0x0001U
11279 +#define TIMESTAMP_TYPE_AGREEMENT       0x0002U
11280 +
11281 +/* Entity Identifier (ECMA 167 1/7.4) */
11282 +typedef struct {
11283 +       Uint8 flags;
11284 +       Uint8 ident[23];
11285 +       Uint8 identSuffix[8];
11286 +} EntityID;
11287 +#define regid EntityID
11288 +
11289 +/* Entity identifier flags (ECMA 167 1/7.4.1) */
11290 +#define ENTITYID_FLAGS_DIRTY           0x01U
11291 +#define ENTITYID_FLAGS_PROTECTED       0x02U
11292 +
11293 +/* Volume Structure Descriptor (ECMA 167 2/9.1) */
11294 +#define STD_ID_LEN     5
11295 +struct VolStructDesc {
11296 +       Uint8 structType;
11297 +       Uint8 stdIdent[STD_ID_LEN];
11298 +       Uint8 structVersion;
11299 +       Uint8 structData[2041];
11300 +};
11301 +
11302 +/* Std structure identifiers (ECMA 167 2/9.1.2) */
11303 +#define STD_ID_BEA01   "BEA01"
11304 +#define STD_ID_BOOT2   "BOOT2"
11305 +#define STD_ID_CD001   "CD001"
11306 +#define STD_ID_CDW02   "CDW02"
11307 +#define STD_ID_NSR02   "NSR02"
11308 +#define STD_ID_NSR03   "NSR03"
11309 +#define STD_ID_TEA01   "TEA01"
11310 +
11311 +/* Beginning Extended Area Descriptor (ECMA 167 2/9.2) */
11312 +struct BeginningExtendedAreaDesc {
11313 +       Uint8 structType;
11314 +       Uint8 stdIdent[STD_ID_LEN];
11315 +       Uint8 structVersion;
11316 +       Uint8 structData[2041];
11317 +};
11318 +
11319 +/* Terminating Extended Area Descriptor (ECMA 167 2/9.3) */
11320 +struct TerminatingExtendedAreaDesc {
11321 +       Uint8 structType;
11322 +       Uint8 stdIdent[STD_ID_LEN];
11323 +       Uint8 structVersion;
11324 +       Uint8 structData[2041];
11325 +};
11326 +
11327 +/* Boot Descriptor (ECMA 167 2/9.4) */
11328 +struct BootDesc {
11329 +       Uint8 structType;
11330 +       Uint8 stdIdent[STD_ID_LEN];
11331 +       Uint8 structVersion;
11332 +       Uint8 reserved1;
11333 +       EntityID architectureType;
11334 +       EntityID bootIdent;
11335 +       Uint32 bootExtLocation;
11336 +       Uint32 bootExtLength;
11337 +       Uint64 loadAddress;
11338 +       Uint64 startAddress;
11339 +       timestamp descCreationDateAndTime;
11340 +       Uint16 flags;
11341 +       Uint8 reserved2[32];
11342 +       Uint8 bootUse[1906];
11343 +};
11344 +
11345 +/* Boot flags (ECMA 167 2/9.4.12) */
11346 +#define BOOT_FLAGS_ERASE       1
11347 +
11348 +/* Extent Descriptor (ECMA 167 3/7.1) */
11349 +typedef struct {
11350 +       Uint32 extLength;
11351 +       Uint32 extLocation;
11352 +} extent_ad;
11353 +
11354 +/* Descriptor Tag (ECMA 167 3/7.2) */
11355 +typedef struct {
11356 +       Uint16 tagIdent;
11357 +       Uint16 descVersion;
11358 +       Uint8 tagChecksum;
11359 +       Uint8 reserved;
11360 +       Uint16 tagSerialNum;
11361 +       Uint16 descCRC;
11362 +       Uint16 descCRCLength;
11363 +       Uint32 tagLocation;
11364 +} tag;
11365 +
11366 +/* Tag Identifiers (ECMA 167 3/7.2.1) */
11367 +#define TID_UNUSED_DESC                        0x0000U
11368 +#define TID_PRIMARY_VOL_DESC           0x0001U
11369 +#define TID_ANCHOR_VOL_DESC_PTR                0x0002U
11370 +#define TID_VOL_DESC_PTR               0x0003U
11371 +#define TID_IMP_USE_VOL_DESC           0x0004U
11372 +#define TID_PARTITION_DESC             0x0005U
11373 +#define TID_LOGICAL_VOL_DESC           0x0006U
11374 +#define TID_UNALLOC_SPACE_DESC         0x0007U
11375 +#define TID_TERMINATING_DESC           0x0008U
11376 +#define TID_LOGICAL_VOL_INTEGRITY_DESC 0x0009U
11377 +
11378 +/* Tag Identifiers (ECMA 167 4/7.2.1) */
11379 +#define TID_FILE_SET_DESC              0x0100U
11380 +#define TID_FILE_IDENT_DESC            0x0101U
11381 +#define TID_ALLOC_EXTENT_DESC          0x0102U
11382 +#define TID_INDIRECT_ENTRY             0x0103U
11383 +#define TID_TERMINAL_ENTRY             0x0104U
11384 +#define TID_FILE_ENTRY                 0x0105U
11385 +#define TID_EXTENDED_ATTRE_HEADER_DESC 0x0106U
11386 +#define TID_UNALLOCATED_SPACE_ENTRY    0x0107U
11387 +#define TID_SPACE_BITMAP_DESC          0x0108U
11388 +#define TID_PARTITION_INTEGRITY_ENTRY  0x0109U
11389 +#define TID_EXTENDED_FILE_ENTRY                0x010AU
11390 +
11391 +/* NSR Descriptor (ECMA 167 3/9.1) */
11392 +struct NSRDesc {
11393 +       Uint8 structType;
11394 +       Uint8 stdIdent[STD_ID_LEN];
11395 +       Uint8 structVersion;
11396 +       Uint8 reserved;
11397 +       Uint8 structData[2040];
11398 +};
11399 +       
11400 +/* Primary Volume Descriptor (ECMA 167 3/10.1) */
11401 +struct PrimaryVolDesc {
11402 +       tag descTag;
11403 +       Uint32 volDescSeqNum;
11404 +       Uint32 primaryVolDescNum;
11405 +       dstring volIdent[32];
11406 +       Uint16 volSeqNum;
11407 +       Uint16 maxVolSeqNum;
11408 +       Uint16 interchangeLvl;
11409 +       Uint16 maxInterchangeLvl;
11410 +       Uint32 charSetList;
11411 +       Uint32 maxCharSetList;
11412 +       dstring volSetIdent[128];
11413 +       charspec descCharSet;
11414 +       charspec explanatoryCharSet;
11415 +       extent_ad volAbstract;
11416 +       extent_ad volCopyright;
11417 +       EntityID appIdent;
11418 +       timestamp recordingDateAndTime;
11419 +       EntityID impIdent;
11420 +       Uint8 impUse[64];
11421 +       Uint32 predecessorVolDescSeqLocation;
11422 +       Uint16 flags;
11423 +       Uint8 reserved[22];
11424 +};
11425 +
11426 +/* Primary volume descriptor flags (ECMA 167 3/10.1.21) */
11427 +#define VOL_SET_IDENT  1
11428 +
11429 +/* Anchor Volume Descriptor Pointer (ECMA 167 3/10.2) */
11430 +struct AnchorVolDescPtr {
11431 +       tag descTag;
11432 +       extent_ad mainVolDescSeqExt;
11433 +       extent_ad reserveVolDescSeqExt;
11434 +       Uint8 reserved[480];
11435 +};
11436 +
11437 +/* Volume Descriptor Pointer (ECMA 167 3/10.3) */
11438 +struct VolDescPtr {
11439 +       tag descTag;
11440 +       Uint32 volDescSeqNum;
11441 +       extent_ad nextVolDescSeqExt;
11442 +       Uint8 reserved[484];
11443 +};
11444 +
11445 +/* Implementation Use Volume Descriptor (ECMA 167 3/10.4) */
11446 +struct ImpUseVolDesc {
11447 +       tag descTag;
11448 +       Uint32 volDescSeqNum;
11449 +       EntityID impIdent;
11450 +       Uint8 impUse[460];
11451 +};
11452 +
11453 +/* Partition Descriptor (ECMA 167 3/10.5) */
11454 +struct PartitionDesc {
11455 +       tag descTag;
11456 +       Uint32 volDescSeqNum;
11457 +       Uint16 partitionFlags;
11458 +       Uint16 partitionNumber;
11459 +       EntityID partitionContents;
11460 +       Uint8 partitionContentsUse[128];
11461 +       Uint32 accessType;
11462 +       Uint32 partitionStartingLocation;
11463 +       Uint32 partitionLength;
11464 +       EntityID impIdent;
11465 +       Uint8 impUse[128];
11466 +       Uint8 reserved[156];
11467 +};
11468 +
11469 +/* Partition Flags (ECMA 167 3/10.5.3) */
11470 +#define PARTITION_FLAGS_ALLOC  1
11471 +
11472 +/* Partition Contents (ECMA 167 3/10.5.5) */
11473 +#define PARTITION_CONTENTS_FDC01       "+FDC01"
11474 +#define PARTITION_CONTENTS_CD001       "+CD001"
11475 +#define PARTITION_CONTENTS_CDW02       "+CDW02"
11476 +#define PARTITION_CONTENTS_NSR02       "+NSR02"
11477 +#define PARTITION_CONTENTS_NSR03       "+NSR03"
11478 +
11479 +/* Partition Access Types (ECMA 167 3/10.5.7) */
11480 +#define PARTITION_ACCESS_NONE  0
11481 +#define PARTITION_ACCESS_R     1
11482 +#define PARTITION_ACCESS_WO    2
11483 +#define PARTITION_ACCESS_RW    3
11484 +#define PARTITION_ACCESS_OW    4
11485 +
11486 +/* Logical Volume Descriptor (ECMA 167 3/10.6) */
11487 +struct LogicalVolDesc {
11488 +       tag descTag;
11489 +       Uint32 volDescSeqNum;
11490 +       charspec descCharSet;
11491 +       dstring logicalVolIdent[128];
11492 +       Uint32 logicalBlockSize;
11493 +       EntityID domainIdent;
11494 +       Uint8 logicalVolContentsUse[16]; /* used to find fileset */
11495 +       Uint32 mapTableLength;
11496 +       Uint32 numPartitionMaps;
11497 +       EntityID impIdent;
11498 +       Uint8 impUse[128];
11499 +       extent_ad integritySeqExt;
11500 +       Uint8 partitionMaps[0];
11501 +};
11502 +
11503 +/* Generic Partition Map (ECMA 167 3/10.7.1) */
11504 +struct GenericPartitionMap {
11505 +       Uint8 partitionMapType;
11506 +       Uint8 partitionMapLength;
11507 +       Uint8 partitionMapping[0];
11508 +};
11509 +
11510 +/* Partition Map Type (ECMA 167 3/10.7.1.1) */
11511 +#define PARTITION_MAP_TYPE_NONE                0
11512 +#define PARTITION_MAP_TYPE_1           1
11513 +#define PARTITION_MAP_TYPE_2           2
11514 +
11515 +/* Type 1 Partition Map (ECMA 167 3/10.7.2) */
11516 +struct GenericPartitionMap1 {
11517 +       Uint8 partitionMapType;
11518 +       Uint8 partitionMapLength;
11519 +       Uint16 volSeqNum;
11520 +       Uint16 partitionNum;
11521 +};
11522 +
11523 +/* Type 2 Partition Map (ECMA 167 3/10.7.3) */
11524 +struct GenericPartitionMap2 {
11525 +       Uint8 partitionMapType; /* 2 */
11526 +       Uint8 partitionMapLength; 
11527 +       Uint8 partitionIdent[62];
11528 +};
11529 +
11530 +/* Unallocated Space Descriptor (ECMA 167 3/10.8) */
11531 +struct UnallocatedSpaceDesc {
11532 +       tag descTag;
11533 +       Uint32 volDescSeqNum;
11534 +       Uint32 numAllocDescs;
11535 +       extent_ad allocDescs[0];
11536 +};
11537 +
11538 +/* Terminating Descriptor (ECMA 3/10.9) */
11539 +struct TerminatingDesc {
11540 +       tag descTag;
11541 +       Uint8 reserved[496];
11542 +};
11543 +
11544 +struct GenericDesc
11545 +{
11546 +        tag descTag;
11547 +        Uint32 volDescSeqNum;
11548 +};
11549 +
11550 +/* Logical Volume Integrity Descriptor (ECMA 167 3/10.10) */
11551 +struct LogicalVolIntegrityDesc {
11552 +       tag descTag;
11553 +       timestamp recordingDateAndTime;
11554 +       Uint32 integrityType;
11555 +       extent_ad nextIntegrityExt;
11556 +       Uint8 logicalVolContentsUse[32];
11557 +       Uint32 numOfPartitions;
11558 +       Uint32 lengthOfImpUse;
11559 +       Uint32 freeSpaceTable[0];
11560 +       Uint32 sizeTable[0];
11561 +       Uint8 impUse[0];
11562 +};
11563 +
11564 +/* Integrity Types (ECMA 167 3/10.10.3) */
11565 +#define INTEGRITY_TYPE_OPEN    0
11566 +#define INTEGRITY_TYPE_CLOSE   1
11567 +
11568 +/* Recorded Address (ECMA 167 4/7.1) */
11569 +typedef struct {
11570 +       Uint32 logicalBlockNum;
11571 +       Uint16 partitionReferenceNum;
11572 +} lb_addr;
11573 +
11574 +/* Extent interpretation (ECMA 167 4/14.14.1.1) */
11575 +#define EXTENT_RECORDED_ALLOCATED               0x00
11576 +#define EXTENT_NOT_RECORDED_ALLOCATED           0x01
11577 +#define EXTENT_NOT_RECORDED_NOT_ALLOCATED       0x02
11578 +#define EXTENT_NEXT_EXTENT_ALLOCDECS            0x03
11579 +
11580 +/* Long Allocation Descriptor (ECMA 167 4/14.14.2) */
11581 +typedef struct {
11582 +       Uint32 extLength;
11583 +       lb_addr extLocation;
11584 +       Uint8 impUse[6];
11585 +} long_ad;
11586 +       /* upper 2 bits of extLength indicate type */
11587 +
11588 +/* File Set Descriptor (ECMA 167 4/14.1) */
11589 +struct FileSetDesc {
11590 +       tag descTag;
11591 +       timestamp recordingDateAndTime;
11592 +       Uint16 interchangeLvl;
11593 +       Uint16 maxInterchangeLvl;
11594 +       Uint32 charSetList;
11595 +       Uint32 maxCharSetList;
11596 +       Uint32 fileSetNum;
11597 +       Uint32 fileSetDescNum;
11598 +       charspec logicalVolIdentCharSet;
11599 +       dstring logicalVolIdent[128];
11600 +       charspec fileSetCharSet;
11601 +       dstring fileSetIdent[32];
11602 +       dstring copyrightFileIdent[32];
11603 +       dstring abstractFileIdent[32];
11604 +       long_ad rootDirectoryICB;
11605 +       EntityID domainIdent;
11606 +       long_ad nextExt;
11607 +       long_ad streamDirectoryICB;
11608 +       Uint8 reserved[32];
11609 +};
11610 +
11611 +/* Short Allocation Descriptor (ECMA 167 4/14.14.1) */
11612 +typedef struct {
11613 +       Uint32 extLength;
11614 +       Uint32 extPosition;
11615 +} short_ad;
11616 +
11617 +/* Partition Header Descriptor (ECMA 167 4/14.3) */
11618 +struct PartitionHeaderDesc {
11619 +       short_ad unallocatedSpaceTable;
11620 +       short_ad unallocatedSpaceBitmap;
11621 +       short_ad partitionIntegrityTable;
11622 +       short_ad freedSpaceTable;
11623 +       short_ad freedSpaceBitmap;
11624 +       Uint8 reserved[88];
11625 +};
11626 +
11627 +/* File Identifier Descriptor (ECMA 167 4/14.4) */
11628 +struct FileIdentDesc
11629 +{
11630 +       tag descTag;
11631 +       Uint16 fileVersionNum; /* 1 */
11632 +       Uint8 fileCharacteristics;
11633 +       Uint8 lengthFileIdent;
11634 +       long_ad icb;
11635 +       Uint16 lengthOfImpUse;
11636 +       Uint8 impUse[0];
11637 +       Uint8 fileIdent[0];
11638 +       Uint8 padding[0];
11639 +};
11640 +
11641 +/* File Characteristics (ECMA 167 4/14.4.3) */
11642 +#define FILE_HIDDEN    1
11643 +#define FILE_DIRECTORY 2
11644 +#define FILE_DELETED   4
11645 +#define FILE_PARENT    8
11646 +#define FILE_METADATA  0x10 /* UDF 2.0 */
11647 +
11648 +/* Allocation Ext Descriptor (ECMA 167 4/14.5) */
11649 +struct AllocExtDesc
11650 +{
11651 +       tag descTag;
11652 +       Uint32 previousAllocExtLocation;
11653 +       Uint32 lengthAllocDescs;
11654 +};
11655 +
11656 +/* ICB Tag (ECMA 167 4/14.6) */
11657 +typedef struct {
11658 +       Uint32 priorRecordedNumDirectEntries;
11659 +       Uint16 strategyType;
11660 +       Uint16 strategyParameter;
11661 +       Uint16 numEntries;
11662 +       Uint8 reserved;
11663 +       Uint8 fileType;
11664 +       lb_addr parentICBLocation;
11665 +       Uint16 flags;
11666 +} icbtag;
11667 +
11668 +/* ICB File Type (ECMA 167 4/14.6.6) */
11669 +#define FILE_TYPE_NONE         0x00U
11670 +#define FILE_TYPE_UNALLOC      0x01U
11671 +#define FILE_TYPE_INTEGRITY    0x02U
11672 +#define FILE_TYPE_INDIRECT     0x03U
11673 +#define FILE_TYPE_DIRECTORY    0x04U
11674 +#define FILE_TYPE_REGULAR      0x05U
11675 +#define FILE_TYPE_BLOCK                0x06U
11676 +#define FILE_TYPE_CHAR         0x07U
11677 +#define FILE_TYPE_EXTENDED     0x08U
11678 +#define FILE_TYPE_FIFO         0x09U
11679 +#define FILE_TYPE_SOCKET       0x0aU
11680 +#define FILE_TYPE_TERMINAL     0x0bU
11681 +#define FILE_TYPE_SYMLINK      0x0cU
11682 +#define FILE_TYPE_STREAMDIR    0x0dU /* ECMA 167 4/13 */
11683 +
11684 +/* ICB Flags (ECMA 167 4/14.6.8) */
11685 +#define ICB_FLAG_ALLOC_MASK    0x0007U
11686 +#define ICB_FLAG_SORTED                0x0008U
11687 +#define ICB_FLAG_NONRELOCATABLE        0x0010U
11688 +#define ICB_FLAG_ARCHIVE       0x0020U
11689 +#define ICB_FLAG_SETUID                0x0040U
11690 +#define ICB_FLAG_SETGID                0x0080U
11691 +#define ICB_FLAG_STICKY                0x0100U
11692 +#define ICB_FLAG_CONTIGUOUS    0x0200U
11693 +#define ICB_FLAG_SYSTEM                0x0400U
11694 +#define ICB_FLAG_TRANSFORMED   0x0800U
11695 +#define ICB_FLAG_MULTIVERSIONS 0x1000U
11696 +
11697 +/* ICB Flags Allocation type(ECMA 167 4/14.6.8) */
11698 +#define ICB_FLAG_AD_SHORT      0
11699 +#define ICB_FLAG_AD_LONG       1
11700 +#define ICB_FLAG_AD_EXTENDED   2
11701 +#define ICB_FLAG_AD_IN_ICB     3
11702 +
11703 +/* Indirect Entry (ECMA 167 4/14.7) */
11704 +struct IndirectEntry {
11705 +       tag descTag;
11706 +       icbtag icbTag;
11707 +       long_ad indirectICB;
11708 +};
11709 +
11710 +/* Terminal Entry (ECMA 167 4/14.8) */
11711 +struct TerminalEntry {
11712 +       tag descTag;
11713 +       icbtag icbTag;
11714 +};
11715 +
11716 +/* File Entry (ECMA 167 4/14.9) */
11717 +struct FileEntry {
11718 +       tag                     descTag;
11719 +       icbtag          icbTag;
11720 +       Uint32          uid;
11721 +       Uint32          gid;
11722 +       Uint32          permissions;
11723 +       Uint16          fileLinkCount;
11724 +       Uint8           recordFormat;
11725 +       Uint8           recordDisplayAttr;
11726 +       Uint32          recordLength;
11727 +       Uint64          informationLength;
11728 +       Uint64          logicalBlocksRecorded;
11729 +       timestamp       accessTime;
11730 +       timestamp       modificationTime;
11731 +       timestamp       attrTime;
11732 +       Uint32          checkpoint;
11733 +       long_ad         extendedAttrICB;
11734 +       EntityID        impIdent;
11735 +       Uint64          uniqueID; /* 0= root, 16- (2^32-1) */
11736 +       Uint32          lengthExtendedAttr;
11737 +       Uint32          lengthAllocDescs;
11738 +       Uint8           extendedAttr[0];
11739 +       Uint8           allocDescs[0];
11740 +};
11741 +
11742 +/* File Permissions (ECMA 167 4/14.9.5) */
11743 +#define PERM_O_EXEC    0x00000001U
11744 +#define PERM_O_WRITE   0x00000002U
11745 +#define PERM_O_READ    0x00000004U
11746 +#define PERM_O_CHATTR  0x00000008U
11747 +#define PERM_O_DELETE  0x00000010U
11748 +#define PERM_G_EXEC    0x00000020U
11749 +#define PERM_G_WRITE   0x00000040U
11750 +#define PERM_G_READ    0x00000080U
11751 +#define PERM_G_CHATTR  0x00000100U
11752 +#define PERM_G_DELETE  0x00000200U
11753 +#define PERM_U_EXEC    0x00000400U
11754 +#define PERM_U_WRITE   0x00000800U
11755 +#define PERM_U_READ    0x00001000U
11756 +#define PERM_U_CHATTR  0x00002000U
11757 +#define PERM_U_DELETE  0x00004000U
11758 +
11759 +/* File Record Format (ECMA 167 4/14.9.7) */
11760 +#define RECORD_FMT_NONE                        0
11761 +#define RECORD_FMT_FIXED_PAD           1
11762 +#define RECORD_FMT_FIXED               2
11763 +#define RECORD_FMT_VARIABLE8           3
11764 +#define RECORD_FMT_VARIABLE16          4
11765 +#define RECORD_FMT_VARIABLE16_MSB      5
11766 +#define RECORD_FMT_VARIABLE32          6
11767 +#define RECORD_FMT_PRINT               7
11768 +#define RECORD_FMT_LF                  8
11769 +#define RECORD_FMT_CR                  9
11770 +#define RECORD_FMT_CRLF                        10
11771 +#define RECORD_FMT_LFCR                        10
11772 +
11773 +/* Extended Attribute Header Descriptor (ECMA 167 4/14.10.1) */
11774 +struct ExtendedAttrHeaderDesc {
11775 +       tag descTag;
11776 +       Uint32 impAttrLocation;
11777 +       Uint32 appAttrLocation;
11778 +};
11779 +
11780 +/* Generic Attribute Format (ECMA 4/14.10.2) */
11781 +struct GenericAttrFormat {
11782 +       Uint32 attrType;
11783 +       Uint8 attrSubtype;
11784 +       Uint8 reserved[3];
11785 +       Uint32 attrLength;
11786 +       Uint8 attrData[0];
11787 +};
11788 +
11789 +/* Character Set Attribute Format (ECMA 4/14.10.3) */
11790 +struct CharSetAttrFormat {
11791 +       Uint32 attrType;                /* 1 */
11792 +       Uint8 attrSubtype;              /* 1 */
11793 +       Uint8 reserved[3];
11794 +       Uint32 attrLength;
11795 +       Uint32 escapeSeqLength;
11796 +       Uint8 charSetType;
11797 +       Uint8 escapeSeq[0];
11798 +};
11799 +
11800 +/* Alternate Permissions (ECMA 167 4/14.10.4) */
11801 +struct AlternatePermissionsExtendedAttr {
11802 +       Uint32 attrType;                /* 3 */
11803 +       Uint8 attrSubtype;              /* 1 */
11804 +       Uint8 reserved[3];
11805 +       Uint32 attrLength;
11806 +       Uint16 ownerIdent;
11807 +       Uint16 groupIdent;
11808 +       Uint16 permission;
11809 +};
11810 +
11811 +/* File Times Extended Attribute (ECMA 167 4/14.10.5) */
11812 +struct FileTimesExtendedAttr {
11813 +       Uint32 attrType;                /* 5 */
11814 +       Uint8 attrSubtype;              /* 1 */
11815 +       Uint8 reserved[3];
11816 +       Uint32 attrLength;
11817 +       Uint32 dataLength;
11818 +       Uint32 fileTimeExistence;
11819 +       Uint8 fileTimes;
11820 +};
11821 +
11822 +/* FileTimeExistence (ECMA 167 4/14.10.5.6) */
11823 +#define FTE_CREATION   0
11824 +#define FTE_DELETION   2
11825 +#define FTE_EFFECTIVE  3
11826 +#define FTE_BACKUP     5
11827 +
11828 +/* Information Times Extended Attribute (ECMA 167 4/14.10.6) */
11829 +struct InfoTimesExtendedAttr {
11830 +       Uint32 attrType;                /* 6 */
11831 +       Uint8 attrSubtype;              /* 1 */
11832 +       Uint8 reserved[3];
11833 +       Uint32 attrLength;
11834 +       Uint32 dataLength;
11835 +       Uint32 infoTimeExistence;
11836 +       Uint8 infoTimes[0];
11837 +};
11838 +
11839 +/* Device Specification Extended Attribute (ECMA 167 4/14.10.7) */
11840 +struct DeviceSpecificationExtendedAttr {
11841 +       Uint32 attrType;                /* 12 */
11842 +       Uint8 attrSubtype;              /* 1 */
11843 +       Uint8 reserved[3];
11844 +       Uint32 attrLength;
11845 +       Uint32 impUseLength;
11846 +       Uint32 majorDeviceIdent;
11847 +       Uint32 minorDeviceIdent;
11848 +       Uint8 impUse[0];
11849 +};
11850 +
11851 +/* Implementation Use Extended Attr (ECMA 167 4/14.10.8) */
11852 +struct ImpUseExtendedAttr {
11853 +       Uint32 attrType;                /* 2048 */
11854 +       Uint8 attrSubtype;              /* 1 */
11855 +       Uint8 reserved[3];
11856 +       Uint32 attrLength;
11857 +       Uint32 impUseLength;
11858 +       EntityID impIdent;
11859 +       Uint8 impUse[0];
11860 +};
11861 +
11862 +/* Application Use Extended Attribute (ECMA 167 4/14.10.9) */
11863 +struct AppUseExtendedAttr {
11864 +       Uint32 attrType;                /* 65536 */
11865 +       Uint8 attrSubtype;              /* 1 */
11866 +       Uint8 reserved[3];
11867 +       Uint32 attrLength;
11868 +       Uint32 appUseLength;
11869 +       EntityID appIdent;
11870 +       Uint8 appUse[0];
11871 +};
11872 +
11873 +#define EXTATTR_CHAR_SET       1
11874 +#define EXTATTR_ALT_PERMS      3
11875 +#define EXTATTR_FILE_TIMES     5
11876 +#define EXTATTR_INFO_TIMES     6
11877 +#define EXTATTR_DEV_SPEC       12
11878 +#define EXTATTR_IMP_USE                2048
11879 +#define EXTATTR_APP_USE                65536
11880 +
11881 +
11882 +/* Unallocated Space Entry (ECMA 167 4/14.11) */
11883 +struct UnallocatedSpaceEntry {
11884 +       tag descTag;
11885 +       icbtag icbTag;
11886 +       Uint32 lengthAllocDescs;
11887 +       Uint8 allocDescs[0];
11888 +};
11889 +
11890 +/* Space Bitmap Descriptor (ECMA 167 4/14.12) */
11891 +struct SpaceBitmapDesc {
11892 +       tag descTag;
11893 +       Uint32 numOfBits;
11894 +       Uint32 numOfBytes;
11895 +       Uint8 bitmap[0];
11896 +};
11897 +
11898 +/* Partition Integrity Entry (ECMA 167 4/14.13) */
11899 +struct PartitionIntegrityEntry {
11900 +       tag descTag;
11901 +       icbtag icbTag;
11902 +       timestamp recordingDateAndTime;
11903 +       Uint8 integrityType;
11904 +       Uint8 reserved[175];
11905 +       EntityID impIdent;
11906 +       Uint8 impUse[256];
11907 +};
11908 +
11909 +/* Extended Allocation Descriptor (ECMA 167 4/14.14.3) */
11910 +typedef struct { /* ECMA 167 4/14.14.3 */
11911 +       Uint32 extLength;
11912 +       Uint32 recordedLength;
11913 +       Uint32 informationLength;
11914 +       lb_addr extLocation;
11915 +} ext_ad;
11916 +
11917 +/* Logical Volume Header Descriptor (ECMA 167 4/14.5) */
11918 +struct LogicalVolHeaderDesc {
11919 +       Uint64 uniqueID;
11920 +       Uint8 reserved[24];
11921 +};
11922 +
11923 +/* Path Component (ECMA 167 4/14.16.1) */
11924 +struct PathComponent {
11925 +       Uint8 componentType;
11926 +       Uint8 lengthComponentIdent;
11927 +       Uint16 componentFileVersionNum;
11928 +       dstring componentIdent[0];
11929 +};
11930 +
11931 +/* File Entry (ECMA 167 4/14.17) */
11932 +struct ExtendedFileEntry {
11933 +       tag                     descTag;
11934 +       icbtag          icbTag;
11935 +       Uint32          uid;
11936 +       Uint32          gid;
11937 +       Uint32          permissions;
11938 +       Uint16          fileLinkCount;
11939 +       Uint8           recordFormat;
11940 +       Uint8           recordDisplayAttr;
11941 +       Uint32          recordLength;
11942 +       Uint64          informationLength;
11943 +       Uint64          objectSize;
11944 +       Uint64          logicalBlocksRecorded;
11945 +       timestamp       accessTime;
11946 +       timestamp       modificationTime;
11947 +       timestamp       createTime;
11948 +       timestamp       attrTime;
11949 +       Uint32          checkpoint;
11950 +       Uint32          reserved;
11951 +       long_ad         extendedAttrICB;
11952 +       long_ad         streamDirectoryICB;
11953 +       EntityID        impIdent;
11954 +       Uint64          uniqueID;
11955 +       Uint32          lengthExtendedAttr;
11956 +       Uint32          lengthAllocDescs;
11957 +       Uint8           extendedAttr[0];
11958 +       Uint8           allocDescs[0];
11959 +};
11960 +#pragma pack()
11961 +
11962 +#endif /* !defined(_LINUX_UDF_167_H) */
11963 diff -Nru linux/include/linux/udf_fs.h linux.new/include/linux/udf_fs.h
11964 --- linux/include/linux/udf_fs.h        Thu Jan  1 01:00:00 1970
11965 +++ linux.new/include/linux/udf_fs.h    Fri Sep  7 11:32:16 2001
11966 @@ -0,0 +1,72 @@
11967 +/*
11968 + * udf_fs.h
11969 + *
11970 + * PURPOSE
11971 + *  Included by fs/filesystems.c
11972 + *
11973 + * DESCRIPTION
11974 + *  OSTA-UDF(tm) = Optical Storage Technology Association
11975 + *  Universal Disk Format.
11976 + *
11977 + *  This code is based on version 2.00 of the UDF specification,
11978 + *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
11979 + *    http://www.osta.org/ *    http://www.ecma.ch/
11980 + *    http://www.iso.org/
11981 + *
11982 + * CONTACTS
11983 + *     E-mail regarding any portion of the Linux UDF file system should be
11984 + *     directed to the development team mailing list (run by majordomo):
11985 + *             linux_udf@hootie.lvld.hp.com
11986 + *
11987 + * COPYRIGHT
11988 + *     This file is distributed under the terms of the GNU General Public
11989 + *     License (GPL). Copies of the GPL can be obtained from:
11990 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
11991 + *     Each contributing author retains all rights to their own work.
11992 + *
11993 + *  (C) 1999-2000 Ben Fennema
11994 + *  (C) 1999-2000 Stelias Computing Inc
11995 + *
11996 + * HISTORY
11997 + *
11998 + */
11999 +
12000 +#if !defined(_LINUX_UDF_FS_H)
12001 +#define _LINUX_UDF_FS_H
12002 +
12003 +
12004 +#define UDF_PREALLOCATE
12005 +#define UDF_DEFAULT_PREALLOC_BLOCKS            8
12006 +
12007 +#define UDFFS_DATE             "2000/05/10"
12008 +#define UDFFS_VERSION  "0.9.2.1"
12009 +
12010 +#define UDFFS_DEBUG
12011 +
12012 +#ifdef UDFFS_DEBUG
12013 +#define udf_debug(f, a...) \
12014 +       { \
12015 +               printk (KERN_DEBUG "UDF-fs DEBUG (%s, %d): %s: ", \
12016 +                       __FILE__, __LINE__, __FUNCTION__); \
12017 +               printk (## f, ## a); \
12018 +       }
12019 +#else
12020 +#define udf_debug(f, a...) /**/
12021 +#endif
12022 +
12023 +#define udf_info(f, a...) \
12024 +               printk (KERN_INFO "UDF-fs INFO " ## f, ## a);
12025 +
12026 +#ifdef __KERNEL__
12027 +
12028 +#ifndef LINUX_VERSION_CODE
12029 +#include <linux/version.h>
12030 +#endif
12031 +
12032 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
12033 +extern int init_udf_fs(void);
12034 +#endif /* 2.2.XX */
12035 +
12036 +#endif /* __KERNEL__ */
12037 +
12038 +#endif /* !defined(_LINUX_UDF_FS_H) */
12039 diff -Nru linux/include/linux/udf_fs_i.h linux.new/include/linux/udf_fs_i.h
12040 --- linux/include/linux/udf_fs_i.h      Thu Jan  1 01:00:00 1970
12041 +++ linux.new/include/linux/udf_fs_i.h  Fri Sep  7 11:32:16 2001
12042 @@ -0,0 +1,58 @@
12043 +/*
12044 + * udf_fs_i.h
12045 + *
12046 + * This file is intended for the Linux kernel/module. 
12047 + *
12048 + * CONTACTS
12049 + *     E-mail regarding any portion of the Linux UDF file system should be
12050 + *     directed to the development team mailing list (run by majordomo):
12051 + *             linux_udf@hootie.lvld.hp.com
12052 + *
12053 + * COPYRIGHT
12054 + *     This file is distributed under the terms of the GNU General Public
12055 + *     License (GPL). Copies of the GPL can be obtained from:
12056 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
12057 + *     Each contributing author retains all rights to their own work.
12058 + */
12059 +
12060 +#if !defined(_LINUX_UDF_FS_I_H)
12061 +#define _LINUX_UDF_FS_I_H
12062 +
12063 +#ifdef __KERNEL__
12064 +
12065 +#ifndef _LINUX_UDF_167_H
12066 +typedef struct
12067 +{
12068 +       __u32 logicalBlockNum;
12069 +       __u16 partitionReferenceNum;
12070 +} lb_addr;
12071 +#endif
12072 +
12073 +struct udf_inode_info
12074 +{
12075 +       long i_uatime;
12076 +       long i_umtime;
12077 +       long i_uctime;
12078 +       /* Physical address of inode */
12079 +       lb_addr i_location;
12080 +       __u64 i_unique;
12081 +       __u32 i_lenEAttr;
12082 +       __u32 i_lenAlloc;
12083 +       __u32 i_next_alloc_block;
12084 +       __u32 i_next_alloc_goal;
12085 +       unsigned i_alloc_type : 3;
12086 +       unsigned i_extended_fe : 1;
12087 +       unsigned i_strat_4096 : 1;
12088 +       unsigned i_new_inode : 1;
12089 +       unsigned reserved : 26;
12090 +};
12091 +
12092 +#endif
12093 +
12094 +/* exported IOCTLs, we have 'l', 0x40-0x7f */
12095 +
12096 +#define UDF_GETEASIZE   _IOR('l', 0x40, int)
12097 +#define UDF_GETEABLOCK  _IOR('l', 0x41, void *)
12098 +#define UDF_GETVOLIDENT _IOR('l', 0x42, void *)
12099 +
12100 +#endif /* !defined(_LINUX_UDF_FS_I_H) */
12101 diff -Nru linux/include/linux/udf_fs_sb.h linux.new/include/linux/udf_fs_sb.h
12102 --- linux/include/linux/udf_fs_sb.h     Thu Jan  1 01:00:00 1970
12103 +++ linux.new/include/linux/udf_fs_sb.h Fri Sep  7 11:32:16 2001
12104 @@ -0,0 +1,124 @@
12105 +/*
12106 + * udf_fs_sb.h
12107 + * 
12108 + * This include file is for the Linux kernel/module.
12109 + *
12110 + * CONTACTS
12111 + *     E-mail regarding any portion of the Linux UDF file system should be
12112 + *     directed to the development team mailing list (run by majordomo):
12113 + *             linux_udf@hootie.lvld.hp.com
12114 + *
12115 + * COPYRIGHT
12116 + *     This file is distributed under the terms of the GNU General Public
12117 + *     License (GPL). Copies of the GPL can be obtained from:
12118 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
12119 + *     Each contributing author retains all rights to their own work.
12120 + */
12121 +
12122 +#if !defined(_LINUX_UDF_FS_SB_H)
12123 +#define _LINUX_UDF_FS_SB_H
12124 +
12125 +#pragma pack(1)
12126 +
12127 +#define UDF_MAX_BLOCK_LOADED   8
12128 +
12129 +#define UDF_TYPE1_MAP15                        0x1511U
12130 +#define UDF_VIRTUAL_MAP15              0x1512U
12131 +#define UDF_VIRTUAL_MAP20              0x2012U
12132 +#define UDF_SPARABLE_MAP15             0x1522U
12133 +
12134 +struct udf_sparing_data
12135 +{
12136 +       __u32   s_spar_loc[4];
12137 +       __u8    s_spar_pshift;
12138 +       __u8    s_spar_indexsize;
12139 +       __u32   *s_spar_map;
12140 +       union
12141 +       {
12142 +               __u8    *s_spar_remap8;
12143 +               __u16   *s_spar_remap16;
12144 +               __u32   *s_spar_remap32;
12145 +       } s_spar_remap;
12146 +};
12147 +
12148 +struct udf_virtual_data
12149 +{
12150 +       __u32   s_num_entries;
12151 +       __u16   s_start_offset;
12152 +};
12153 +
12154 +struct udf_bitmap
12155 +{
12156 +       __u32                           s_extLength;
12157 +       __u32                           s_extPosition;
12158 +       __u16                           s_nr_groups;
12159 +       struct buffer_head      **s_block_bitmap;
12160 +};
12161 +
12162 +struct udf_part_map
12163 +{
12164 +       union
12165 +       {
12166 +               struct udf_bitmap       *s_bitmap;
12167 +               struct inode            *s_table;
12168 +       }               s_uspace;
12169 +       union
12170 +       {
12171 +               struct udf_bitmap       *s_bitmap;
12172 +               struct inode            *s_table;
12173 +       }               s_fspace;
12174 +       __u32   s_partition_root;
12175 +       __u32   s_partition_len;
12176 +       __u16   s_partition_type;
12177 +       __u16   s_partition_num;
12178 +       union
12179 +       {
12180 +               struct udf_sparing_data s_sparing;
12181 +               struct udf_virtual_data s_virtual;
12182 +       } s_type_specific;
12183 +       __u32   (*s_partition_func)(struct super_block *, __u32, __u16, __u32);
12184 +       __u16   s_volumeseqnum;
12185 +       __u16   s_partition_flags;
12186 +};
12187 +
12188 +#pragma pack()
12189 +
12190 +struct udf_sb_info
12191 +{
12192 +       struct udf_part_map     *s_partmaps;
12193 +       __u8                            s_volident[32];
12194 +
12195 +       /* Overall info */
12196 +       __u16                           s_partitions;
12197 +       __u16                           s_partition;
12198 +
12199 +       /* Sector headers */
12200 +       __u32                           s_session;
12201 +       __u32                           s_anchor[4];
12202 +       __u32                           s_lastblock;
12203 +
12204 +       struct buffer_head      *s_lvidbh;
12205 +
12206 +       /* Default permissions */
12207 +       mode_t                          s_umask;
12208 +       gid_t                           s_gid;
12209 +       uid_t                           s_uid;
12210 +
12211 +       /* Root Info */
12212 +       time_t                          s_recordtime;
12213 +
12214 +       /* Fileset Info */
12215 +       __u16                           s_serialnum;
12216 +
12217 +       /* highest UDF revision we have recorded to this media */
12218 +       __u16                           s_udfrev;
12219 +
12220 +       /* Miscellaneous flags */
12221 +       __u32                           s_flags;
12222 +
12223 +       /* VAT inode */
12224 +       struct inode            *s_vat;
12225 +
12226 +};
12227 +
12228 +#endif /* !defined(_LINUX_UDF_FS_SB_H) */
12229 diff -Nru linux/include/linux/udf_udf.h linux.new/include/linux/udf_udf.h
12230 --- linux/include/linux/udf_udf.h       Thu Jan  1 01:00:00 1970
12231 +++ linux.new/include/linux/udf_udf.h   Fri Sep  7 11:32:16 2001
12232 @@ -0,0 +1,227 @@
12233 +#if !defined(_LINUX_UDF_UDF_H)
12234 +#define _LINUX_UDF_UDF_H
12235 +/*
12236 + * udf_udf.h
12237 + *
12238 + * PURPOSE
12239 + *     OSTA-UDF(tm) format specification [based on ECMA 167 standard].
12240 + *     http://www.osta.org/
12241 + *
12242 + * CONTACTS
12243 + *     E-mail regarding any portion of the Linux UDF file system should be
12244 + *     directed to the development team mailing list (run by majordomo):
12245 + *             linux_udf@hootie.lvld.hp.com
12246 + *
12247 + * COPYRIGHT
12248 + *     This file is distributed under the terms of the GNU General Public
12249 + *     License (GPL). Copies of the GPL can be obtained from:
12250 + *             ftp://prep.ai.mit.edu/pub/gnu/GPL
12251 + *     Each contributing author retains all rights to their own work.
12252 + *
12253 + * HISTORY
12254 + *     July 1, 1997 - Andrew E. Mileski
12255 + *     Written, tested, and released.
12256 + *
12257 + * 10/2/98 dgb changed UDF_ID_DEVELOPER
12258 + * 11/26/98 bf  changed UDF_ID_DEVELOPER, 
12259 + * 12/5/98 dgb  updated include file hierarchy, more UDF definitions
12260 + */
12261 +
12262 +/* based on ECMA 167 structure definitions */
12263 +#include <linux/udf_167.h>
12264 +
12265 +#pragma pack(1)
12266 +
12267 +/* -------- Basic types and constants ----------- */
12268 +/* UDF character set (UDF 1.50 2.1.2) */
12269 +#define UDF_CHAR_SET_TYPE      0
12270 +#define UDF_CHAR_SET_INFO      "OSTA Compressed Unicode"
12271 +
12272 +#define UDF_ID_DEVELOPER       "*Linux UDFFS"
12273
12274 +/* UDF 1.02 2.2.6.4 */
12275 +struct LogicalVolIntegrityDescImpUse
12276 +{
12277 +       EntityID        impIdent;
12278 +       Uint32          numFiles;
12279 +       Uint32          numDirs;
12280 +       Uint16          minUDFReadRev;
12281 +       Uint16          minUDFWriteRev;
12282 +       Uint16          maxUDFWriteRev;
12283 +};
12284 +
12285 +/* UDF 1.02 2.2.7.2 */
12286 +/* LVInformation may be present in ImpUseVolDesc.impUse */
12287 +struct ImpUseVolDescImpUse
12288 +{
12289 +       charspec        LVICharset;
12290 +       dstring         logicalVolIdent[128];
12291 +       dstring         LVInfo1[36];
12292 +       dstring         LVInfo2[36];
12293 +       dstring         LVInfo3[36];
12294 +       EntityID        impIdent;
12295 +       Uint8           impUse[128];
12296 +};
12297 +
12298 +struct UdfPartitionMap2
12299 +{
12300 +        Uint8           partitionMapType;
12301 +        Uint8           partitionMapLength;
12302 +        Uint8           reserved1[2];
12303 +        EntityID        partIdent;
12304 +        Uint16          volSeqNum;
12305 +        Uint16          partitionNum;
12306 +        Uint8           reserved2[24];
12307 +};
12308 +
12309 +/* UDF 1.5 2.2.8 */
12310 +struct VirtualPartitionMap
12311 +{
12312 +       Uint8           partitionMapType;       /* 2 */
12313 +       Uint8           partitionMapLength;     /* 64 */
12314 +       Uint8           reserved1[2];           /* #00 */
12315 +       EntityID        partIdent;
12316 +       Uint16          volSeqNum;
12317 +       Uint16          partitionNum;
12318 +       Uint8           reserved2[24];          /* #00 */
12319 +};
12320 +
12321 +/* UDF 1.5 2.2.9 */
12322 +struct SparablePartitionMap
12323 +{
12324 +       Uint8           partitionMapType;       /* 2 */
12325 +       Uint8           partitionMapLength;     /* 64 */
12326 +       Uint8           reserved1[2];           /* #00 */
12327 +       EntityID        partIdent;              /* Flags = 0 */
12328 +                                               /* Id = UDF_ID_SPARABLE */
12329 +                                               /* IdSuf = 2.1.5.3 */
12330 +       Uint16          volSeqNum;
12331 +       Uint16          partitionNum;
12332 +       Uint16          packetLength;           /* 32 */
12333 +       Uint8           numSparingTables;
12334 +       Uint8           reserved2[1];           /* #00 */
12335 +       Uint32          sizeSparingTable;
12336 +       Uint32          locSparingTable[4];
12337 +};
12338
12339 +/* DVD Copyright Management Info, see UDF 1.02 3.3.4.5.1.2 */
12340 +/* when ImpUseExtendedAttr.impIdent= "*UDF DVD CGMS Info" */
12341 +struct DVDCopyrightImpUse {
12342 +       Uint16 headerChecksum;
12343 +       Uint8  CGMSInfo;
12344 +       Uint8  dataType;
12345 +       Uint8  protectionSystemInfo[4];
12346 +};
12347 +
12348 +/* the impUse of long_ad used in AllocDescs  - UDF 1.02 2.3.10.1 */
12349 +struct ADImpUse
12350 +{
12351 +       Uint16 flags;
12352 +       Uint8  impUse[4];
12353 +};
12354 +
12355 +/* UDF 1.02 2.3.10.1 */
12356 +#define UDF_EXTENT_LENGTH_MASK         0x3FFFFFFF
12357 +#define UDF_EXTENT_FLAG_MASK           0xc0000000
12358 +#define UDF_EXTENT_FLAG_ERASED         0x40000000
12359 +
12360 +/* 
12361 + * Important!  VirtualAllocationTables are 
12362 + * very different between 1.5 and 2.0!
12363 + */
12364 +
12365 +/* ----------- 1.5 ------------- */
12366 +/* UDF 1.5 2.2.10 */
12367 +#define FILE_TYPE_VAT15                0x0U
12368 +
12369 +/* UDF 1.5 2.2.10 - VAT layout: */
12370 +struct VirutalAllocationTable15 {
12371 +       Uint32 VirtualSector[0];
12372 +       EntityID        ident;
12373 +       Uint32  previousVATICB;
12374 +   };  
12375 +/* where number of VirtualSector's is (VATSize-36)/4 */
12376 +
12377 +/* ----------- 2.0 ------------- */
12378 +/* UDF 2.0 2.2.10 */
12379 +#define FILE_TYPE_VAT20                0xf8U
12380 +
12381 +/* UDF 2.0 2.2.10 (different from 1.5!) */
12382 +struct VirtualAllocationTable20 {
12383 +       Uint16 lengthHeader;
12384 +       Uint16 lengthImpUse;
12385 +       dstring logicalVolIdent[128];
12386 +       Uint32  previousVatICBLoc;
12387 +       Uint32  numFIDSFiles;
12388 +       Uint32  numFIDSDirectories; /* non-parent */
12389 +       Uint16  minReadRevision;
12390 +       Uint16  minWriteRevision;
12391 +       Uint16  maxWriteRevision;
12392 +       Uint16  reserved;
12393 +       Uint8   impUse[0];
12394 +       Uint32  vatEntry[0];
12395 +};
12396 +
12397 +/* Sparing maps, see UDF 1.5 2.2.11 */
12398 +typedef struct {
12399 +       Uint32  origLocation;
12400 +       Uint32  mappedLocation;
12401 +} SparingEntry;
12402 +
12403 +/* sparing maps, see UDF 2.0 2.2.11 */
12404 +struct SparingTable {
12405 +       tag     descTag;
12406 +       EntityID sparingIdent; /* *UDF Sparing Table */
12407 +       Uint16   reallocationTableLen;
12408 +       Uint16   reserved;      /* #00 */
12409 +       Uint32   sequenceNum;
12410 +       SparingEntry mapEntry[0];
12411 +};
12412 +
12413 +/* Entity Identifiers (UDF 1.50 6.1) */
12414 +#define        UDF_ID_COMPLIANT        "*OSTA UDF Compliant"
12415 +#define UDF_ID_LV_INFO         "*UDF LV Info"
12416 +#define UDF_ID_FREE_EA         "*UDF FreeEASpace"
12417 +#define UDF_ID_FREE_APP_EA     "*UDF FreeAppEASpace"
12418 +#define UDF_ID_DVD_CGMS                "*UDF DVD CGMS Info"
12419 +#define UDF_ID_OS2_EA          "*UDF OS/2 EA"
12420 +#define UDF_ID_OS2_EA_LENGTH   "*UDF OS/2 EALength"
12421 +#define UDF_ID_MAC_VOLUME      "*UDF Mac VolumeInfo"
12422 +#define UDF_ID_MAC_FINDER      "*UDF Mac FinderInfo"
12423 +#define UDF_ID_MAC_UNIQUE      "*UDF Mac UniqueIDTable"
12424 +#define UDF_ID_MAC_RESOURCE    "*UDF Mac ResourceFork"
12425 +#define UDF_ID_VIRTUAL         "*UDF Virtual Partition"
12426 +#define UDF_ID_SPARABLE                "*UDF Sparable Partition"
12427 +#define UDF_ID_ALLOC           "*UDF Virtual Alloc Tbl"
12428 +#define UDF_ID_SPARING         "*UDF Sparing Table"
12429 +
12430 +/* Operating System Identifiers (UDF 1.50 6.3) */
12431 +#define UDF_OS_CLASS_UNDEF     0x00U
12432 +#define UDF_OS_CLASS_DOS       0x01U
12433 +#define UDF_OS_CLASS_OS2       0x02U
12434 +#define UDF_OS_CLASS_MAC       0x03U
12435 +#define UDF_OS_CLASS_UNIX      0x04U
12436 +#define UDF_OS_CLASS_WIN95     0x05U
12437 +#define UDF_OS_CLASS_WINNT     0x06U
12438 +#define UDF_OS_ID_UNDEF                0x00U
12439 +#define UDF_OS_ID_DOS          0x00U
12440 +#define UDF_OS_ID_OS2          0x00U
12441 +#define UDF_OS_ID_MAC          0x00U
12442 +#define UDF_OS_ID_UNIX         0x00U
12443 +#define UDF_OS_ID_WIN95                0x00U
12444 +#define UDF_OS_ID_WINNT                0x00U
12445 +#define UDF_OS_ID_AIX          0x01U
12446 +#define UDF_OS_ID_SOLARIS      0x02U
12447 +#define UDF_OS_ID_HPUX         0x03U
12448 +#define UDF_OS_ID_IRIX         0x04U
12449 +#define UDF_OS_ID_LINUX                0x05U
12450 +#define UDF_OS_ID_MKLINUX      0x06U
12451 +#define UDF_OS_ID_FREEBSD      0x07U
12452 +
12453 +#define UDF_NAME_PAD   4
12454 +#define UDF_NAME_LEN   255
12455 +#define UDF_PATH_LEN   1023
12456 +
12457 +#pragma pack()
12458 +
12459 +#endif /* !defined(_LINUX_UDF_FMT_H) */
This page took 1.281526 seconds and 3 git commands to generate.