OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [udf/] [super.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * super.c
3
 *
4
 * PURPOSE
5
 *  Super block routines for the OSTA-UDF(tm) filesystem.
6
 *
7
 * DESCRIPTION
8
 *  OSTA-UDF(tm) = Optical Storage Technology Association
9
 *  Universal Disk Format.
10
 *
11
 *  This code is based on version 2.00 of the UDF specification,
12
 *  and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
13
 *    http://www.osta.org/
14
 *    http://www.ecma.ch/
15
 *    http://www.iso.org/
16
 *
17
 * CONTACTS
18
 *  E-mail regarding any portion of the Linux UDF file system should be
19
 *  directed to the development team mailing list (run by majordomo):
20
 *        linux_udf@hpesjro.fc.hp.com
21
 *
22
 * COPYRIGHT
23
 *  This file is distributed under the terms of the GNU General Public
24
 *  License (GPL). Copies of the GPL can be obtained from:
25
 *    ftp://prep.ai.mit.edu/pub/gnu/GPL
26
 *  Each contributing author retains all rights to their own work.
27
 *
28
 *  (C) 1998 Dave Boynton
29
 *  (C) 1998-2001 Ben Fennema
30
 *  (C) 2000 Stelias Computing Inc
31
 *
32
 * HISTORY
33
 *
34
 *  09/24/98 dgb  changed to allow compiling outside of kernel, and
35
 *                added some debugging.
36
 *  10/01/98 dgb  updated to allow (some) possibility of compiling w/2.0.34
37
 *  10/16/98      attempting some multi-session support
38
 *  10/17/98      added freespace count for "df"
39
 *  11/11/98 gr   added novrs option
40
 *  11/26/98 dgb  added fileset,anchor mount options
41
 *  12/06/98 blf  really hosed things royally. vat/sparing support. sequenced vol descs
42
 *                rewrote option handling based on isofs
43
 *  12/20/98      find the free space bitmap (if it exists)
44
 */
45
 
46
#include "udfdecl.h"    
47
 
48
#include <linux/config.h>
49
#include <linux/version.h>
50
#include <linux/blkdev.h>
51
#include <linux/slab.h>
52
#include <linux/kernel.h>
53
#include <linux/locks.h>
54
#include <linux/module.h>
55
#include <linux/stat.h>
56
#include <linux/cdrom.h>
57
#include <linux/nls.h>
58
#include <asm/byteorder.h>
59
 
60
#include <linux/udf_fs.h>
61
#include "udf_sb.h"
62
#include "udf_i.h"
63
 
64
#include <linux/init.h>
65
#include <asm/uaccess.h>
66
 
67
#define VDS_POS_PRIMARY_VOL_DESC        0
68
#define VDS_POS_UNALLOC_SPACE_DESC      1
69
#define VDS_POS_LOGICAL_VOL_DESC        2
70
#define VDS_POS_PARTITION_DESC          3
71
#define VDS_POS_IMP_USE_VOL_DESC        4
72
#define VDS_POS_VOL_DESC_PTR            5
73
#define VDS_POS_TERMINATING_DESC        6
74
#define VDS_POS_LENGTH                  7
75
 
76
static char error_buf[1024];
77
 
78
/* These are the "meat" - everything else is stuffing */
79
static struct super_block *udf_read_super(struct super_block *, void *, int);
80
static void udf_put_super(struct super_block *);
81
static void udf_write_super(struct super_block *);
82
static int udf_remount_fs(struct super_block *, int *, char *);
83
static int udf_check_valid(struct super_block *, int, int);
84
static int udf_vrs(struct super_block *sb, int silent);
85
static int udf_load_partition(struct super_block *, lb_addr *);
86
static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
87
static void udf_load_logicalvolint(struct super_block *, extent_ad);
88
static void udf_find_anchor(struct super_block *);
89
static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
90
static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
91
static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
92
static void udf_load_partdesc(struct super_block *, struct buffer_head *);
93
static void udf_open_lvid(struct super_block *);
94
static void udf_close_lvid(struct super_block *);
95
static unsigned int udf_count_free(struct super_block *);
96
static int udf_statfs(struct super_block *, struct statfs *);
97
 
98
/* UDF filesystem type */
99
static DECLARE_FSTYPE_DEV(udf_fstype, "udf", udf_read_super);
100
 
101
/* Superblock operations */
102
static struct super_operations udf_sb_ops = {
103
        read_inode:             udf_read_inode,
104
        write_inode:            udf_write_inode,
105
        put_inode:              udf_put_inode,
106
        delete_inode:           udf_delete_inode,
107
        put_super:              udf_put_super,
108
        write_super:            udf_write_super,
109
        statfs:                 udf_statfs,
110
        remount_fs:             udf_remount_fs,
111
};
112
 
113
struct udf_options
114
{
115
        unsigned char novrs;
116
        unsigned int blocksize;
117
        unsigned int session;
118
        unsigned int lastblock;
119
        unsigned int anchor;
120
        unsigned int volume;
121
        unsigned short partition;
122
        unsigned int fileset;
123
        unsigned int rootdir;
124
        unsigned int flags;
125
        mode_t umask;
126
        gid_t gid;
127
        uid_t uid;
128
        struct nls_table *nls_map;
129
};
130
 
131
static int __init init_udf_fs(void)
132
{
133
        printk(KERN_NOTICE "udf: registering filesystem\n");
134
        return register_filesystem(&udf_fstype);
135
}
136
 
137
static void __exit exit_udf_fs(void)
138
{
139
        printk(KERN_NOTICE "udf: unregistering filesystem\n");
140
        unregister_filesystem(&udf_fstype);
141
}
142
 
143
EXPORT_NO_SYMBOLS;
144
 
145
module_init(init_udf_fs)
146
module_exit(exit_udf_fs)
147
 
148
/*
149
 * udf_parse_options
150
 *
151
 * PURPOSE
152
 *      Parse mount options.
153
 *
154
 * DESCRIPTION
155
 *      The following mount options are supported:
156
 *
157
 *      gid=            Set the default group.
158
 *      umask=          Set the default umask.
159
 *      uid=            Set the default user.
160
 *      bs=                     Set the block size.
161
 *      unhide          Show otherwise hidden files.
162
 *      undelete        Show deleted files in lists.
163
 *      adinicb         Embed data in the inode (default)
164
 *      noadinicb       Don't embed data in the inode
165
 *      shortad         Use short ad's
166
 *      longad          Use long ad's (default)
167
 *      nostrict        Unset strict conformance
168
 *      iocharset=      Set the NLS character set
169
 *
170
 *      The remaining are for debugging and disaster recovery:
171
 *
172
 *      novrs           Skip volume sequence recognition
173
 *
174
 *      The following expect a offset from 0.
175
 *
176
 *      session=        Set the CDROM session (default= last session)
177
 *      anchor=         Override standard anchor location. (default= 256)
178
 *      volume=         Override the VolumeDesc location. (unused)
179
 *      partition=      Override the PartitionDesc location. (unused)
180
 *      lastblock=      Set the last block of the filesystem/
181
 *
182
 *      The following expect a offset from the partition root.
183
 *
184
 *      fileset=        Override the fileset block location. (unused)
185
 *      rootdir=        Override the root directory location. (unused)
186
 *              WARNING: overriding the rootdir to a non-directory may
187
 *              yield highly unpredictable results.
188
 *
189
 * PRE-CONDITIONS
190
 *      options         Pointer to mount options string.
191
 *      uopts           Pointer to mount options variable.
192
 *
193
 * POST-CONDITIONS
194
 *      <return>        0        Mount options parsed okay.
195
 *      <return>        -1      Error parsing mount options.
196
 *
197
 * HISTORY
198
 *      July 1, 1997 - Andrew E. Mileski
199
 *      Written, tested, and released.
200
 */
201
 
202
static int
203
udf_parse_options(char *options, struct udf_options *uopt)
204
{
205
        char *opt, *val;
206
 
207
        uopt->novrs = 0;
208
        uopt->blocksize = 2048;
209
        uopt->partition = 0xFFFF;
210
        uopt->session = 0xFFFFFFFF;
211
        uopt->lastblock = 0;
212
        uopt->anchor = 0;
213
        uopt->volume = 0xFFFFFFFF;
214
        uopt->rootdir = 0xFFFFFFFF;
215
        uopt->fileset = 0xFFFFFFFF;
216
        uopt->nls_map = NULL;
217
 
218
        if (!options)
219
                return 1;
220
 
221
        for (opt = strtok(options, ","); opt; opt = strtok(NULL, ","))
222
        {
223
                /* Make "opt=val" into two strings */
224
                val = strchr(opt, '=');
225
                if (val)
226
                        *(val++) = 0;
227
                if (!strcmp(opt, "novrs") && !val)
228
                        uopt->novrs = 1;
229
                else if (!strcmp(opt, "bs") && val)
230
                        uopt->blocksize = simple_strtoul(val, NULL, 0);
231
                else if (!strcmp(opt, "unhide") && !val)
232
                        uopt->flags |= (1 << UDF_FLAG_UNHIDE);
233
                else if (!strcmp(opt, "undelete") && !val)
234
                        uopt->flags |= (1 << UDF_FLAG_UNDELETE);
235
                else if (!strcmp(opt, "noadinicb") && !val)
236
                        uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
237
                else if (!strcmp(opt, "adinicb") && !val)
238
                        uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
239
                else if (!strcmp(opt, "shortad") && !val)
240
                        uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
241
                else if (!strcmp(opt, "longad") && !val)
242
                        uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
243
                else if (!strcmp(opt, "gid") && val)
244
                        uopt->gid = simple_strtoul(val, NULL, 0);
245
                else if (!strcmp(opt, "umask") && val)
246
                        uopt->umask = simple_strtoul(val, NULL, 0);
247
                else if (!strcmp(opt, "nostrict") && !val)
248
                        uopt->flags &= ~(1 << UDF_FLAG_STRICT);
249
                else if (!strcmp(opt, "uid") && val)
250
                        uopt->uid = simple_strtoul(val, NULL, 0);
251
                else if (!strcmp(opt, "session") && val)
252
                        uopt->session = simple_strtoul(val, NULL, 0);
253
                else if (!strcmp(opt, "lastblock") && val)
254
                        uopt->lastblock = simple_strtoul(val, NULL, 0);
255
                else if (!strcmp(opt, "anchor") && val)
256
                        uopt->anchor = simple_strtoul(val, NULL, 0);
257
                else if (!strcmp(opt, "volume") && val)
258
                        uopt->volume = simple_strtoul(val, NULL, 0);
259
                else if (!strcmp(opt, "partition") && val)
260
                        uopt->partition = simple_strtoul(val, NULL, 0);
261
                else if (!strcmp(opt, "fileset") && val)
262
                        uopt->fileset = simple_strtoul(val, NULL, 0);
263
                else if (!strcmp(opt, "rootdir") && val)
264
                        uopt->rootdir = simple_strtoul(val, NULL, 0);
265
#ifdef CONFIG_NLS
266
                else if (!strcmp(opt, "iocharset") && val)
267
                {
268
                        uopt->nls_map = load_nls(val);
269
                        uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
270
                }
271
#endif
272
                else if (!strcmp(opt, "utf8") && !val)
273
                        uopt->flags |= (1 << UDF_FLAG_UTF8);
274
                else if (val)
275
                {
276
                        printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
277
                                opt, val);
278
                        return 0;
279
                }
280
                else
281
                {
282
                        printk(KERN_ERR "udf: bad mount option \"%s\"\n",
283
                                opt);
284
                        return 0;
285
                }
286
        }
287
        return 1;
288
}
289
 
290
void
291
udf_write_super(struct super_block *sb)
292
{
293
        if (!(sb->s_flags & MS_RDONLY))
294
                udf_open_lvid(sb);
295
        sb->s_dirt = 0;
296
}
297
 
298
static int
299
udf_remount_fs(struct super_block *sb, int *flags, char *options)
300
{
301
        struct udf_options uopt;
302
 
303
        uopt.flags = UDF_SB(sb)->s_flags ;
304
        uopt.uid   = UDF_SB(sb)->s_uid ;
305
        uopt.gid   = UDF_SB(sb)->s_gid ;
306
        uopt.umask = UDF_SB(sb)->s_umask ;
307
 
308
        if ( !udf_parse_options(options, &uopt) )
309
                return -EINVAL;
310
 
311
        UDF_SB(sb)->s_flags = uopt.flags;
312
        UDF_SB(sb)->s_uid   = uopt.uid;
313
        UDF_SB(sb)->s_gid   = uopt.gid;
314
        UDF_SB(sb)->s_umask = uopt.umask;
315
 
316
#if UDFFS_RW != 1
317
        *flags |= MS_RDONLY;
318
#endif
319
 
320
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
321
                return 0;
322
        if (*flags & MS_RDONLY)
323
                udf_close_lvid(sb);
324
        else
325
                udf_open_lvid(sb);
326
 
327
        return 0;
328
}
329
 
330
/*
331
 * udf_set_blocksize
332
 *
333
 * PURPOSE
334
 *      Set the block size to be used in all transfers.
335
 *
336
 * DESCRIPTION
337
 *      To allow room for a DMA transfer, it is best to guess big when unsure.
338
 *      This routine picks 2048 bytes as the blocksize when guessing. This
339
 *      should be adequate until devices with larger block sizes become common.
340
 *
341
 *      Note that the Linux kernel can currently only deal with blocksizes of
342
 *      512, 1024, 2048, 4096, and 8192 bytes.
343
 *
344
 * PRE-CONDITIONS
345
 *      sb                      Pointer to _locked_ superblock.
346
 *
347
 * POST-CONDITIONS
348
 *      sb->s_blocksize         Blocksize.
349
 *      sb->s_blocksize_bits    log2 of blocksize.
350
 *      <return>        0        Blocksize is valid.
351
 *      <return>        1       Blocksize is invalid.
352
 *
353
 * HISTORY
354
 *      July 1, 1997 - Andrew E. Mileski
355
 *      Written, tested, and released.
356
 */
357
static  int
358
udf_set_blocksize(struct super_block *sb, int bsize)
359
{
360
        /* Use specified block size if specified */
361
        if (bsize)
362
                sb->s_blocksize = bsize;
363
        if (get_hardsect_size(sb->s_dev) > sb->s_blocksize)
364
                sb->s_blocksize = get_hardsect_size(sb->s_dev);
365
 
366
        /* Block size must be an even multiple of 512 */
367
        switch (sb->s_blocksize)
368
        {
369
                case 512: sb->s_blocksize_bits = 9;     break;
370
                case 1024: sb->s_blocksize_bits = 10; break;
371
                case 2048: sb->s_blocksize_bits = 11; break;
372
                case 4096: sb->s_blocksize_bits = 12; break;
373
                case 8192: sb->s_blocksize_bits = 13; break;
374
                default:
375
                {
376
                        udf_debug("Bad block size (%ld)\n", sb->s_blocksize);
377
                        printk(KERN_ERR "udf: bad block size (%ld)\n", sb->s_blocksize);
378
                        return 0;
379
                }
380
        }
381
 
382
        /* Set the block size */
383
        set_blocksize(sb->s_dev, sb->s_blocksize);
384
        return sb->s_blocksize;
385
}
386
 
387
static int
388
udf_vrs(struct super_block *sb, int silent)
389
{
390
        struct volStructDesc *vsd = NULL;
391
        int sector = 32768;
392
        int sectorsize;
393
        struct buffer_head *bh = NULL;
394
        int iso9660=0;
395
        int nsr02=0;
396
        int nsr03=0;
397
 
398
        /* Block size must be a multiple of 512 */
399
        if (sb->s_blocksize & 511)
400
                return 0;
401
 
402
        if (sb->s_blocksize < sizeof(struct volStructDesc))
403
                sectorsize = sizeof(struct volStructDesc);
404
        else
405
                sectorsize = sb->s_blocksize;
406
 
407
        sector += (UDF_SB_SESSION(sb) << sb->s_blocksize_bits);
408
 
409
        udf_debug("Starting at sector %u (%ld byte sectors)\n",
410
                (sector >> sb->s_blocksize_bits), sb->s_blocksize);
411
        /* Process the sequence (if applicable) */
412
        for (;!nsr02 && !nsr03; sector += sectorsize)
413
        {
414
                /* Read a block */
415
                bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
416
                if (!bh)
417
                        break;
418
 
419
                /* Look for ISO  descriptors */
420
                vsd = (struct volStructDesc *)(bh->b_data +
421
                        (sector & (sb->s_blocksize - 1)));
422
 
423
                if (vsd->stdIdent[0] == 0)
424
                {
425
                        udf_release_data(bh);
426
                        break;
427
                }
428
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
429
                {
430
                        iso9660 = sector;
431
                        switch (vsd->structType)
432
                        {
433
                                case 0:
434
                                        udf_debug("ISO9660 Boot Record found\n");
435
                                        break;
436
                                case 1:
437
                                        udf_debug("ISO9660 Primary Volume Descriptor found\n");
438
                                        break;
439
                                case 2:
440
                                        udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
441
                                        break;
442
                                case 3:
443
                                        udf_debug("ISO9660 Volume Partition Descriptor found\n");
444
                                        break;
445
                                case 255:
446
                                        udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
447
                                        break;
448
                                default:
449
                                        udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
450
                                        break;
451
                        }
452
                }
453
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
454
                {
455
                }
456
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
457
                {
458
                        udf_release_data(bh);
459
                        break;
460
                }
461
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
462
                {
463
                        nsr02 = sector;
464
                }
465
                else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
466
                {
467
                        nsr03 = sector;
468
                }
469
                udf_release_data(bh);
470
        }
471
 
472
        if (nsr03)
473
                return nsr03;
474
        else if (nsr02)
475
                return nsr02;
476
        else if (sector - (UDF_SB_SESSION(sb) << sb->s_blocksize_bits) == 32768)
477
                return -1;
478
        else
479
                return 0;
480
}
481
 
482
/*
483
 * udf_find_anchor
484
 *
485
 * PURPOSE
486
 *      Find an anchor volume descriptor.
487
 *
488
 * PRE-CONDITIONS
489
 *      sb                      Pointer to _locked_ superblock.
490
 *      lastblock               Last block on media.
491
 *
492
 * POST-CONDITIONS
493
 *      <return>                1 if not found, 0 if ok
494
 *
495
 * HISTORY
496
 *      July 1, 1997 - Andrew E. Mileski
497
 *      Written, tested, and released.
498
 */
499
static void
500
udf_find_anchor(struct super_block *sb)
501
{
502
        int lastblock = UDF_SB_LASTBLOCK(sb);
503
        struct buffer_head *bh = NULL;
504
        uint16_t ident;
505
        uint32_t location;
506
        int i;
507
 
508
        if (lastblock)
509
        {
510
                int varlastblock = udf_variable_to_fixed(lastblock);
511
                int last[] =  { lastblock, lastblock - 2,
512
                                lastblock - 150, lastblock - 152,
513
                                varlastblock, varlastblock - 2,
514
                                varlastblock - 150, varlastblock - 152 };
515
 
516
                lastblock = 0;
517
 
518
                /* Search for an anchor volume descriptor pointer */
519
 
520
                /*  according to spec, anchor is in either:
521
                 *     block 256
522
                 *     lastblock-256
523
                 *     lastblock
524
                 *  however, if the disc isn't closed, it could be 512 */
525
 
526
                for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
527
                {
528
                        if (last[i] < 0 || !(bh = sb_bread(sb, last[i])))
529
                        {
530
                                ident = location = 0;
531
                        }
532
                        else
533
                        {
534
                                ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
535
                                location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
536
                                udf_release_data(bh);
537
                        }
538
 
539
                        if (ident == TAG_IDENT_AVDP)
540
                        {
541
                                if (location == last[i] - UDF_SB_SESSION(sb))
542
                                {
543
                                        lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
544
                                        UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
545
                                }
546
                                else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
547
                                {
548
                                        UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
549
                                        lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
550
                                        UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
551
                                }
552
                                else
553
                                        udf_debug("Anchor found at block %d, location mismatch %d.\n",
554
                                                last[i], location);
555
                        }
556
                        else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE)
557
                        {
558
                                lastblock = last[i];
559
                                UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
560
                        }
561
                        else
562
                        {
563
                                if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256)))
564
                                {
565
                                        ident = location = 0;
566
                                }
567
                                else
568
                                {
569
                                        ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
570
                                        location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
571
                                        udf_release_data(bh);
572
                                }
573
 
574
                                if (ident == TAG_IDENT_AVDP &&
575
                                        location == last[i] - 256 - UDF_SB_SESSION(sb))
576
                                {
577
                                        lastblock = last[i];
578
                                        UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
579
                                }
580
                                else
581
                                {
582
                                        if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb))))
583
                                        {
584
                                                ident = location = 0;
585
                                        }
586
                                        else
587
                                        {
588
                                                ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
589
                                                location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
590
                                                udf_release_data(bh);
591
                                        }
592
 
593
                                        if (ident == TAG_IDENT_AVDP &&
594
                                                location == udf_variable_to_fixed(last[i]) - 256)
595
                                        {
596
                                                UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
597
                                                lastblock = udf_variable_to_fixed(last[i]);
598
                                                UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
599
                                        }
600
                                }
601
                        }
602
                }
603
        }
604
 
605
        if (!lastblock)
606
        {
607
                /* We havn't found the lastblock. check 312 */
608
                if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb))))
609
                {
610
                        ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
611
                        location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
612
                        udf_release_data(bh);
613
 
614
                        if (ident == TAG_IDENT_AVDP && location == 256)
615
                                UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
616
                }
617
        }
618
 
619
        for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
620
        {
621
                if (UDF_SB_ANCHOR(sb)[i])
622
                {
623
                        if (!(bh = udf_read_tagged(sb,
624
                                UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
625
                        {
626
                                UDF_SB_ANCHOR(sb)[i] = 0;
627
                        }
628
                        else
629
                        {
630
                                udf_release_data(bh);
631
                                if ((ident != TAG_IDENT_AVDP) && (i ||
632
                                        (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
633
                                {
634
                                        UDF_SB_ANCHOR(sb)[i] = 0;
635
                                }
636
                        }
637
                }
638
        }
639
 
640
        UDF_SB_LASTBLOCK(sb) = lastblock;
641
}
642
 
643
static int
644
udf_find_fileset(struct super_block *sb, lb_addr *fileset, lb_addr *root)
645
{
646
        struct buffer_head *bh = NULL;
647
        long lastblock;
648
        uint16_t ident;
649
 
650
        if (fileset->logicalBlockNum != 0xFFFFFFFF ||
651
                fileset->partitionReferenceNum != 0xFFFF)
652
        {
653
                bh = udf_read_ptagged(sb, *fileset, 0, &ident);
654
 
655
                if (!bh)
656
                        return 1;
657
                else if (ident != TAG_IDENT_FSD)
658
                {
659
                        udf_release_data(bh);
660
                        return 1;
661
                }
662
 
663
        }
664
 
665
        if (!bh) /* Search backwards through the partitions */
666
        {
667
                lb_addr newfileset;
668
 
669
                return 1;
670
 
671
                for (newfileset.partitionReferenceNum=UDF_SB_NUMPARTS(sb)-1;
672
                        (newfileset.partitionReferenceNum != 0xFFFF &&
673
                                fileset->logicalBlockNum == 0xFFFFFFFF &&
674
                                fileset->partitionReferenceNum == 0xFFFF);
675
                        newfileset.partitionReferenceNum--)
676
                {
677
                        lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
678
                        newfileset.logicalBlockNum = 0;
679
 
680
                        do
681
                        {
682
                                bh = udf_read_ptagged(sb, newfileset, 0, &ident);
683
                                if (!bh)
684
                                {
685
                                        newfileset.logicalBlockNum ++;
686
                                        continue;
687
                                }
688
 
689
                                switch (ident)
690
                                {
691
                                        case TAG_IDENT_SBD:
692
                                        {
693
                                                struct spaceBitmapDesc *sp;
694
                                                sp = (struct spaceBitmapDesc *)bh->b_data;
695
                                                newfileset.logicalBlockNum += 1 +
696
                                                        ((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
697
                                                                >> sb->s_blocksize_bits);
698
                                                udf_release_data(bh);
699
                                                break;
700
                                        }
701
                                        case TAG_IDENT_FSD:
702
                                        {
703
                                                *fileset = newfileset;
704
                                                break;
705
                                        }
706
                                        default:
707
                                        {
708
                                                newfileset.logicalBlockNum ++;
709
                                                udf_release_data(bh);
710
                                                bh = NULL;
711
                                                break;
712
                                        }
713
                                }
714
                        }
715
                        while (newfileset.logicalBlockNum < lastblock &&
716
                                fileset->logicalBlockNum == 0xFFFFFFFF &&
717
                                fileset->partitionReferenceNum == 0xFFFF);
718
                }
719
        }
720
 
721
        if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
722
                fileset->partitionReferenceNum != 0xFFFF) && bh)
723
        {
724
                udf_debug("Fileset at block=%d, partition=%d\n",
725
                        fileset->logicalBlockNum, fileset->partitionReferenceNum);
726
 
727
                UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
728
                udf_load_fileset(sb, bh, root);
729
                udf_release_data(bh);
730
                return 0;
731
        }
732
        return 1;
733
}
734
 
735
static void
736
udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
737
{
738
        struct primaryVolDesc *pvoldesc;
739
        time_t recording;
740
        long recording_usec;
741
        struct ustr instr;
742
        struct ustr outstr;
743
 
744
        pvoldesc = (struct primaryVolDesc *)bh->b_data;
745
 
746
        if ( udf_stamp_to_time(&recording, &recording_usec,
747
                lets_to_cpu(pvoldesc->recordingDateAndTime)) )
748
        {
749
                timestamp ts;
750
                ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
751
                udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
752
                        recording, recording_usec,
753
                        ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
754
                UDF_SB_RECORDTIME(sb) = recording;
755
        }
756
 
757
        if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) )
758
        {
759
                if (udf_CS0toUTF8(&outstr, &instr))
760
                {
761
                        strncpy( UDF_SB_VOLIDENT(sb), outstr.u_name,
762
                                outstr.u_len > 31 ? 31 : outstr.u_len);
763
                        udf_debug("volIdent[] = '%s'\n", UDF_SB_VOLIDENT(sb));
764
                }
765
        }
766
 
767
        if ( !udf_build_ustr(&instr, pvoldesc->volSetIdent, 128) )
768
        {
769
                if (udf_CS0toUTF8(&outstr, &instr))
770
                        udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
771
        }
772
}
773
 
774
static void
775
udf_load_fileset(struct super_block *sb, struct buffer_head *bh, lb_addr *root)
776
{
777
        struct fileSetDesc *fset;
778
 
779
        fset = (struct fileSetDesc *)bh->b_data;
780
 
781
        *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation);
782
 
783
        UDF_SB_SERIALNUM(sb) = le16_to_cpu(fset->descTag.tagSerialNum);
784
 
785
        udf_debug("Rootdir at block=%d, partition=%d\n",
786
                root->logicalBlockNum, root->partitionReferenceNum);
787
}
788
 
789
static void
790
udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
791
{
792
        struct partitionDesc *p;
793
        int i;
794
 
795
        p = (struct partitionDesc *)bh->b_data;
796
 
797
        for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
798
        {
799
                udf_debug("Searching map: (%d == %d)\n",
800
                        UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));
801
                if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber))
802
                {
803
                        UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
804
                        UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb);
805
                        if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
806
                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
807
                        if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
808
                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;
809
                        if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)
810
                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;
811
                        if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)
812
                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;
813
 
814
                        if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||
815
                                !strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
816
                        {
817
                                struct partitionHeaderDesc *phd;
818
 
819
                                phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
820
                                if (phd->unallocSpaceTable.extLength)
821
                                {
822
                                        lb_addr loc = { le32_to_cpu(phd->unallocSpaceTable.extPosition), i };
823
 
824
                                        UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
825
                                                udf_iget(sb, loc);
826
                                        UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
827
                                        udf_debug("unallocSpaceTable (part %d) @ %ld\n",
828
                                                i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
829
                                }
830
                                if (phd->unallocSpaceBitmap.extLength)
831
                                {
832
                                        UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
833
                                        if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL)
834
                                        {
835
                                                UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
836
                                                        le32_to_cpu(phd->unallocSpaceBitmap.extLength);
837
                                                UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
838
                                                        le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
839
                                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
840
                                                udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
841
                                                        i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
842
                                        }
843
                                }
844
                                if (phd->partitionIntegrityTable.extLength)
845
                                        udf_debug("partitionIntegrityTable (part %d)\n", i);
846
                                if (phd->freedSpaceTable.extLength)
847
                                {
848
                                        lb_addr loc = { le32_to_cpu(phd->freedSpaceTable.extPosition), i };
849
 
850
                                        UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
851
                                                udf_iget(sb, loc);
852
                                        UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
853
                                        udf_debug("freedSpaceTable (part %d) @ %ld\n",
854
                                                i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
855
                                }
856
                                if (phd->freedSpaceBitmap.extLength)
857
                                {
858
                                        UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
859
                                        if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL)
860
                                        {
861
                                                UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
862
                                                        le32_to_cpu(phd->freedSpaceBitmap.extLength);
863
                                                UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
864
                                                        le32_to_cpu(phd->freedSpaceBitmap.extPosition);
865
                                                UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
866
                                                udf_debug("freedSpaceBitmap (part %d) @ %d\n",
867
                                                        i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
868
                                        }
869
                                }
870
                        }
871
                        break;
872
                }
873
        }
874
        if (i == UDF_SB_NUMPARTS(sb))
875
        {
876
                udf_debug("Partition (%d) not found in partition map\n", le16_to_cpu(p->partitionNumber));
877
        }
878
        else
879
        {
880
                udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
881
                        le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
882
                        UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
883
        }
884
}
885
 
886
static int
887
udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset)
888
{
889
        struct logicalVolDesc *lvd;
890
        int i, j, offset;
891
        uint8_t type;
892
 
893
        lvd = (struct logicalVolDesc *)bh->b_data;
894
 
895
        UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
896
 
897
        for (i=0,offset=0;
898
                 i<UDF_SB_NUMPARTS(sb) && offset<le32_to_cpu(lvd->mapTableLength);
899
                 i++,offset+=((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength)
900
        {
901
                type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
902
                if (type == 1)
903
                {
904
                        struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);
905
                        UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
906
                        UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
907
                        UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
908
                        UDF_SB_PARTFUNC(sb,i) = NULL;
909
                }
910
                else if (type == 2)
911
                {
912
                        struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
913
                        if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
914
                        {
915
                                if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0150)
916
                                {
917
                                        UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
918
                                        UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
919
                                }
920
                                else if (le16_to_cpu(((uint16_t *)upm2->partIdent.identSuffix)[0]) == 0x0200)
921
                                {
922
                                        UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
923
                                        UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
924
                                }
925
                        }
926
                        else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
927
                        {
928
                                uint32_t loc;
929
                                uint16_t ident;
930
                                struct sparingTable *st;
931
                                struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);
932
 
933
                                UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
934
                                UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
935
                                for (j=0; j<spm->numSparingTables; j++)
936
                                {
937
                                        loc = le32_to_cpu(spm->locSparingTable[j]);
938
                                        UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =
939
                                                udf_read_tagged(sb, loc, loc, &ident);
940
                                        if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL)
941
                                        {
942
                                                st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
943
                                                if (ident != 0 ||
944
                                                        strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
945
                                                {
946
                                                        udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
947
                                                        UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
948
                                                }
949
                                        }
950
                                }
951
                                UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
952
                        }
953
                        else
954
                        {
955
                                udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
956
                                continue;
957
                        }
958
                        UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
959
                        UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
960
                }
961
                udf_debug("Partition (%d:%d) type %d on volume %d\n",
962
                        i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
963
        }
964
 
965
        if (fileset)
966
        {
967
                long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
968
 
969
                *fileset = lelb_to_cpu(la->extLocation);
970
                udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
971
                        fileset->logicalBlockNum,
972
                        fileset->partitionReferenceNum);
973
        }
974
        if (lvd->integritySeqExt.extLength)
975
                udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
976
        return 0;
977
}
978
 
979
/*
980
 * udf_load_logicalvolint
981
 *
982
 */
983
static void
984
udf_load_logicalvolint(struct super_block *sb, extent_ad loc)
985
{
986
        struct buffer_head *bh = NULL;
987
        uint16_t ident;
988
 
989
        while (loc.extLength > 0 &&
990
                (bh = udf_read_tagged(sb, loc.extLocation,
991
                        loc.extLocation, &ident)) &&
992
                ident == TAG_IDENT_LVID)
993
        {
994
                UDF_SB_LVIDBH(sb) = bh;
995
 
996
                if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
997
                        udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
998
 
999
                if (UDF_SB_LVIDBH(sb) != bh)
1000
                        udf_release_data(bh);
1001
                loc.extLength -= sb->s_blocksize;
1002
                loc.extLocation ++;
1003
        }
1004
        if (UDF_SB_LVIDBH(sb) != bh)
1005
                udf_release_data(bh);
1006
}
1007
 
1008
/*
1009
 * udf_process_sequence
1010
 *
1011
 * PURPOSE
1012
 *      Process a main/reserve volume descriptor sequence.
1013
 *
1014
 * PRE-CONDITIONS
1015
 *      sb                      Pointer to _locked_ superblock.
1016
 *      block                   First block of first extent of the sequence.
1017
 *      lastblock               Lastblock of first extent of the sequence.
1018
 *
1019
 * HISTORY
1020
 *      July 1, 1997 - Andrew E. Mileski
1021
 *      Written, tested, and released.
1022
 */
1023
static  int
1024
udf_process_sequence(struct super_block *sb, long block, long lastblock, lb_addr *fileset)
1025
{
1026
        struct buffer_head *bh = NULL;
1027
        struct udf_vds_record vds[VDS_POS_LENGTH];
1028
        struct generic_desc *gd;
1029
        struct volDescPtr *vdp;
1030
        int done=0;
1031
        int i,j;
1032
        uint32_t vdsn;
1033
        uint16_t ident;
1034
        long next_s = 0, next_e = 0;
1035
 
1036
        memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
1037
 
1038
        /* Read the main descriptor sequence */
1039
        for (;(!done && block <= lastblock); block++)
1040
        {
1041
 
1042
                bh = udf_read_tagged(sb, block, block, &ident);
1043
                if (!bh)
1044
                        break;
1045
 
1046
                /* Process each descriptor (ISO 13346 3/8.3-8.4) */
1047
                gd = (struct generic_desc *)bh->b_data;
1048
                vdsn = le32_to_cpu(gd->volDescSeqNum);
1049
                switch (ident)
1050
                {
1051
                        case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
1052
                                if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum)
1053
                                {
1054
                                        vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
1055
                                        vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
1056
                                }
1057
                                break;
1058
                        case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
1059
                                if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum)
1060
                                {
1061
                                        vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
1062
                                        vds[VDS_POS_VOL_DESC_PTR].block = block;
1063
 
1064
                                        vdp = (struct volDescPtr *)bh->b_data;
1065
                                        next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
1066
                                        next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
1067
                                        next_e = next_e >> sb->s_blocksize_bits;
1068
                                        next_e += next_s;
1069
                                }
1070
                                break;
1071
                        case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
1072
                                if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum)
1073
                                {
1074
                                        vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
1075
                                        vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
1076
                                }
1077
                                break;
1078
                        case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
1079
                                if (!vds[VDS_POS_PARTITION_DESC].block)
1080
                                        vds[VDS_POS_PARTITION_DESC].block = block;
1081
                                break;
1082
                        case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
1083
                                if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum)
1084
                                {
1085
                                        vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
1086
                                        vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
1087
                                }
1088
                                break;
1089
                        case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
1090
                                if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum)
1091
                                {
1092
                                        vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
1093
                                        vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
1094
                                }
1095
                                break;
1096
                        case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
1097
                                vds[VDS_POS_TERMINATING_DESC].block = block;
1098
                                if (next_e)
1099
                                {
1100
                                        block = next_s;
1101
                                        lastblock = next_e;
1102
                                        next_s = next_e = 0;
1103
                                }
1104
                                else
1105
                                        done = 1;
1106
                                break;
1107
                }
1108
                udf_release_data(bh);
1109
        }
1110
        for (i=0; i<VDS_POS_LENGTH; i++)
1111
        {
1112
                if (vds[i].block)
1113
                {
1114
                        bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
1115
 
1116
                        if (i == VDS_POS_PRIMARY_VOL_DESC)
1117
                                udf_load_pvoldesc(sb, bh);
1118
                        else if (i == VDS_POS_LOGICAL_VOL_DESC)
1119
                                udf_load_logicalvol(sb, bh, fileset);
1120
                        else if (i == VDS_POS_PARTITION_DESC)
1121
                        {
1122
                                struct buffer_head *bh2 = NULL;
1123
                                udf_load_partdesc(sb, bh);
1124
                                for (j=vds[i].block+1; j<vds[VDS_POS_TERMINATING_DESC].block; j++)
1125
                                {
1126
                                        bh2 = udf_read_tagged(sb, j, j, &ident);
1127
                                        gd = (struct generic_desc *)bh2->b_data;
1128
                                        if (ident == TAG_IDENT_PD)
1129
                                                udf_load_partdesc(sb, bh2);
1130
                                        udf_release_data(bh2);
1131
                                }
1132
                        }
1133
                        udf_release_data(bh);
1134
                }
1135
        }
1136
 
1137
        return 0;
1138
}
1139
 
1140
/*
1141
 * udf_check_valid()
1142
 */
1143
static int
1144
udf_check_valid(struct super_block *sb, int novrs, int silent)
1145
{
1146
        long block;
1147
 
1148
        if (novrs)
1149
        {
1150
                udf_debug("Validity check skipped because of novrs option\n");
1151
                return 0;
1152
        }
1153
        /* Check that it is NSR02 compliant */
1154
        /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
1155
        else if ((block = udf_vrs(sb, silent)) == -1)
1156
        {
1157
                udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
1158
                if (!UDF_SB_LASTBLOCK(sb))
1159
                        UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
1160
                return 0;
1161
        }
1162
        else
1163
                return !block;
1164
}
1165
 
1166
static int
1167
udf_load_partition(struct super_block *sb, lb_addr *fileset)
1168
{
1169
        struct anchorVolDescPtr *anchor;
1170
        uint16_t ident;
1171
        struct buffer_head *bh;
1172
        long main_s, main_e, reserve_s, reserve_e;
1173
        int i, j;
1174
 
1175
        if (!sb)
1176
                return 1;
1177
 
1178
        for (i=0; i<sizeof(UDF_SB_ANCHOR(sb))/sizeof(int); i++)
1179
        {
1180
                if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
1181
                        UDF_SB_ANCHOR(sb)[i], UDF_SB_ANCHOR(sb)[i], &ident)))
1182
                {
1183
                        anchor = (struct anchorVolDescPtr *)bh->b_data;
1184
 
1185
                        /* Locate the main sequence */
1186
                        main_s = le32_to_cpu( anchor->mainVolDescSeqExt.extLocation );
1187
                        main_e = le32_to_cpu( anchor->mainVolDescSeqExt.extLength );
1188
                        main_e = main_e >> sb->s_blocksize_bits;
1189
                        main_e += main_s;
1190
 
1191
                        /* Locate the reserve sequence */
1192
                        reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
1193
                        reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
1194
                        reserve_e = reserve_e >> sb->s_blocksize_bits;
1195
                        reserve_e += reserve_s;
1196
 
1197
                        udf_release_data(bh);
1198
 
1199
                        /* Process the main & reserve sequences */
1200
                        /* responsible for finding the PartitionDesc(s) */
1201
                        if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
1202
                                udf_process_sequence(sb, reserve_s, reserve_e, fileset)))
1203
                        {
1204
                                break;
1205
                        }
1206
                }
1207
        }
1208
 
1209
        if (i == sizeof(UDF_SB_ANCHOR(sb))/sizeof(int))
1210
        {
1211
                udf_debug("No Anchor block found\n");
1212
                return 1;
1213
        }
1214
        else
1215
                udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
1216
 
1217
        for (i=0; i<UDF_SB_NUMPARTS(sb); i++)
1218
        {
1219
                switch UDF_SB_PARTTYPE(sb, i)
1220
                {
1221
                        case UDF_VIRTUAL_MAP15:
1222
                        case UDF_VIRTUAL_MAP20:
1223
                        {
1224
                                lb_addr ino;
1225
 
1226
                                if (!UDF_SB_LASTBLOCK(sb))
1227
                                {
1228
                                        UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
1229
                                        udf_find_anchor(sb);
1230
                                }
1231
 
1232
                                if (!UDF_SB_LASTBLOCK(sb))
1233
                                {
1234
                                        udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
1235
                                        return 1;
1236
                                }
1237
 
1238
                                for (j=0; j<UDF_SB_NUMPARTS(sb); j++)
1239
                                {
1240
                                        if (j != i &&
1241
                                                UDF_SB_PARTVSN(sb,i) == UDF_SB_PARTVSN(sb,j) &&
1242
                                                UDF_SB_PARTNUM(sb,i) == UDF_SB_PARTNUM(sb,j))
1243
                                        {
1244
                                                ino.partitionReferenceNum = j;
1245
                                                ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) -
1246
                                                        UDF_SB_PARTROOT(sb,j);
1247
                                                break;
1248
                                        }
1249
                                }
1250
 
1251
                                if (j == UDF_SB_NUMPARTS(sb))
1252
                                        return 1;
1253
 
1254
                                if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
1255
                                        return 1;
1256
 
1257
                                if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
1258
                                {
1259
                                        UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb));
1260
                                        UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
1261
                                }
1262
                                else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
1263
                                {
1264
                                        struct buffer_head *bh = NULL;
1265
                                        uint32_t pos;
1266
 
1267
                                        pos = udf_block_map(UDF_SB_VAT(sb), 0);
1268
                                        bh = sb_bread(sb, pos);
1269
                                        UDF_SB_TYPEVIRT(sb,i).s_start_offset =
1270
                                                le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
1271
                                                        udf_ext0_offset(UDF_SB_VAT(sb));
1272
                                        UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
1273
                                                UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
1274
                                        udf_release_data(bh);
1275
                                }
1276
                                UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
1277
                                UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
1278
                        }
1279
                }
1280
        }
1281
        return 0;
1282
}
1283
 
1284
static void udf_open_lvid(struct super_block *sb)
1285
{
1286
        if (UDF_SB_LVIDBH(sb))
1287
        {
1288
                int i;
1289
                timestamp cpu_time;
1290
 
1291
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1292
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1293
                if (udf_time_to_stamp(&cpu_time, CURRENT_TIME, CURRENT_UTIME))
1294
                        UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
1295
                UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
1296
 
1297
                UDF_SB_LVID(sb)->descTag.descCRC =
1298
                        cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
1299
                        le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
1300
 
1301
                UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
1302
                for (i=0; i<16; i++)
1303
                        if (i != 4)
1304
                                UDF_SB_LVID(sb)->descTag.tagChecksum +=
1305
                                        ((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
1306
 
1307
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
1308
        }
1309
}
1310
 
1311
static void udf_close_lvid(struct super_block *sb)
1312
{
1313
        if (UDF_SB_LVIDBH(sb) &&
1314
                UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN)
1315
        {
1316
                int i;
1317
                timestamp cpu_time;
1318
 
1319
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1320
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1321
                if (udf_time_to_stamp(&cpu_time, CURRENT_TIME, CURRENT_UTIME))
1322
                        UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
1323
                if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
1324
                        UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
1325
                if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
1326
                        UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
1327
                if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
1328
                        UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
1329
                UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_CLOSE;
1330
 
1331
                UDF_SB_LVID(sb)->descTag.descCRC =
1332
                        cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
1333
                        le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
1334
 
1335
                UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
1336
                for (i=0; i<16; i++)
1337
                        if (i != 4)
1338
                                UDF_SB_LVID(sb)->descTag.tagChecksum +=
1339
                                        ((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
1340
 
1341
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
1342
        }
1343
}
1344
 
1345
/*
1346
 * udf_read_super
1347
 *
1348
 * PURPOSE
1349
 *      Complete the specified super block.
1350
 *
1351
 * PRE-CONDITIONS
1352
 *      sb                      Pointer to superblock to complete - never NULL.
1353
 *      sb->s_dev               Device to read suberblock from.
1354
 *      options                 Pointer to mount options.
1355
 *      silent                  Silent flag.
1356
 *
1357
 * HISTORY
1358
 *      July 1, 1997 - Andrew E. Mileski
1359
 *      Written, tested, and released.
1360
 */
1361
static struct super_block *
1362
udf_read_super(struct super_block *sb, void *options, int silent)
1363
{
1364
        int i;
1365
        struct inode *inode=NULL;
1366
        struct udf_options uopt;
1367
        lb_addr rootdir, fileset;
1368
 
1369
        uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
1370
        uopt.uid = -1;
1371
        uopt.gid = -1;
1372
        uopt.umask = 0;
1373
 
1374
        memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
1375
 
1376
#if UDFFS_RW != 1
1377
        sb->s_flags |= MS_RDONLY;
1378
#endif
1379
 
1380
        if (!udf_parse_options((char *)options, &uopt))
1381
                goto error_out;
1382
 
1383
        if (uopt.flags & (1 << UDF_FLAG_UTF8) &&
1384
            uopt.flags & (1 << UDF_FLAG_NLS_MAP))
1385
        {
1386
                udf_error(sb, "udf_read_super",
1387
                        "utf8 cannot be combined with iocharset\n");
1388
                goto error_out;
1389
        }
1390
#ifdef CONFIG_NLS
1391
        if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
1392
        {
1393
                uopt.nls_map = load_nls_default();
1394
                if (!uopt.nls_map)
1395
                        uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP);
1396
                else
1397
                        udf_debug("Using default NLS map\n");
1398
        }
1399
#endif
1400
        if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP)))
1401
                uopt.flags |= (1 << UDF_FLAG_UTF8);
1402
 
1403
        fileset.logicalBlockNum = 0xFFFFFFFF;
1404
        fileset.partitionReferenceNum = 0xFFFF;
1405
 
1406
        UDF_SB(sb)->s_flags = uopt.flags;
1407
        UDF_SB(sb)->s_uid = uopt.uid;
1408
        UDF_SB(sb)->s_gid = uopt.gid;
1409
        UDF_SB(sb)->s_umask = uopt.umask;
1410
        UDF_SB(sb)->s_nls_map = uopt.nls_map;
1411
 
1412
        /* Set the block size for all transfers */
1413
        if (!udf_set_blocksize(sb, uopt.blocksize))
1414
                goto error_out;
1415
 
1416
        if ( uopt.session == 0xFFFFFFFF )
1417
                UDF_SB_SESSION(sb) = udf_get_last_session(sb);
1418
        else
1419
                UDF_SB_SESSION(sb) = uopt.session;
1420
 
1421
        udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
1422
 
1423
        UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
1424
        UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
1425
        UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
1426
        UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256;
1427
 
1428
        if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
1429
        {
1430
                printk("UDF-fs: No VRS found\n");
1431
                goto error_out;
1432
        }
1433
 
1434
        udf_find_anchor(sb);
1435
 
1436
        /* Fill in the rest of the superblock */
1437
        sb->s_op = &udf_sb_ops;
1438
        sb->dq_op = NULL;
1439
        sb->s_dirt = 0;
1440
        sb->s_magic = UDF_SUPER_MAGIC;
1441
 
1442
        if (udf_load_partition(sb, &fileset))
1443
        {
1444
                printk("UDF-fs: No partition found (1)\n");
1445
                goto error_out;
1446
        }
1447
 
1448
        udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
1449
 
1450
        if ( UDF_SB_LVIDBH(sb) )
1451
        {
1452
                uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
1453
                uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
1454
                /* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
1455
 
1456
                if (minUDFReadRev > UDF_MAX_READ_VERSION)
1457
                {
1458
                        printk("UDF-fs: minUDFReadRev=%x (max is %x)\n",
1459
                                UDF_SB_LVIDIU(sb)->minUDFReadRev, UDF_MAX_READ_VERSION);
1460
                        goto error_out;
1461
                }
1462
                else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
1463
                {
1464
                        sb->s_flags |= MS_RDONLY;
1465
                }
1466
 
1467
                UDF_SB_UDFREV(sb) = minUDFWriteRev;
1468
 
1469
                if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE)
1470
                        UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE);
1471
                if (minUDFReadRev >= UDF_VERS_USE_STREAMS)
1472
                        UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS);
1473
        }
1474
 
1475
        if ( !UDF_SB_NUMPARTS(sb) )
1476
        {
1477
                printk("UDF-fs: No partition found (2)\n");
1478
                goto error_out;
1479
        }
1480
 
1481
        if ( udf_find_fileset(sb, &fileset, &rootdir) )
1482
        {
1483
                printk("UDF-fs: No fileset found\n");
1484
                goto error_out;
1485
        }
1486
 
1487
        if (!silent)
1488
        {
1489
                timestamp ts;
1490
                udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
1491
                udf_info("UDF %s-%s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
1492
                        UDFFS_VERSION, UDFFS_RW ? "rw" : "ro", UDFFS_DATE,
1493
                        UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
1494
                        ts.typeAndTimezone);
1495
        }
1496
        if (!(sb->s_flags & MS_RDONLY))
1497
                udf_open_lvid(sb);
1498
 
1499
        /* Assign the root inode */
1500
        /* assign inodes by physical block number */
1501
        /* perhaps it's not extensible enough, but for now ... */
1502
        inode = udf_iget(sb, rootdir);
1503
        if (!inode)
1504
        {
1505
                printk("UDF-fs: Error in udf_iget, block=%d, partition=%d\n",
1506
                        rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
1507
                goto error_out;
1508
        }
1509
 
1510
        /* Allocate a dentry for the root inode */
1511
        sb->s_root = d_alloc_root(inode);
1512
        if (!sb->s_root)
1513
        {
1514
                printk("UDF-fs: Couldn't allocate root dentry\n");
1515
                iput(inode);
1516
                goto error_out;
1517
        }
1518
        sb->s_maxbytes = MAX_LFS_FILESIZE;
1519
        return sb;
1520
 
1521
error_out:
1522
        if (UDF_SB_VAT(sb))
1523
                iput(UDF_SB_VAT(sb));
1524
        if (UDF_SB_NUMPARTS(sb))
1525
        {
1526
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1527
                        iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1528
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1529
                        iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1530
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1531
                {
1532
                        for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_uspace); i++)
1533
                        {
1534
                                if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i))
1535
                                        udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i));
1536
                        }
1537
                        kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
1538
                }
1539
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1540
                {
1541
                        for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_fspace); i++)
1542
                        {
1543
                                if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i))
1544
                                        udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i));
1545
                        }
1546
                        kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
1547
                }
1548
                if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
1549
                {
1550
                        for (i=0; i<4; i++)
1551
                                udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
1552
                }
1553
        }
1554
#ifdef CONFIG_NLS
1555
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1556
                unload_nls(UDF_SB(sb)->s_nls_map);
1557
#endif
1558
        if (!(sb->s_flags & MS_RDONLY))
1559
                udf_close_lvid(sb);
1560
        udf_release_data(UDF_SB_LVIDBH(sb));
1561
        UDF_SB_FREE(sb);
1562
        return NULL;
1563
}
1564
 
1565
void udf_error(struct super_block *sb, const char *function,
1566
        const char *fmt, ...)
1567
{
1568
        va_list args;
1569
 
1570
        if (!(sb->s_flags & MS_RDONLY))
1571
        {
1572
                /* mark sb error */
1573
                sb->s_dirt = 1;
1574
        }
1575
        va_start(args, fmt);
1576
        vsprintf(error_buf, fmt, args);
1577
        va_end(args);
1578
        printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
1579
                bdevname(sb->s_dev), function, error_buf);
1580
}
1581
 
1582
void udf_warning(struct super_block *sb, const char *function,
1583
        const char *fmt, ...)
1584
{
1585
        va_list args;
1586
 
1587
        va_start (args, fmt);
1588
        vsprintf(error_buf, fmt, args);
1589
        va_end(args);
1590
        printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
1591
                bdevname(sb->s_dev), function, error_buf);
1592
}
1593
 
1594
/*
1595
 * udf_put_super
1596
 *
1597
 * PURPOSE
1598
 *      Prepare for destruction of the superblock.
1599
 *
1600
 * DESCRIPTION
1601
 *      Called before the filesystem is unmounted.
1602
 *
1603
 * HISTORY
1604
 *      July 1, 1997 - Andrew E. Mileski
1605
 *      Written, tested, and released.
1606
 */
1607
static void
1608
udf_put_super(struct super_block *sb)
1609
{
1610
        int i;
1611
 
1612
        if (UDF_SB_VAT(sb))
1613
                iput(UDF_SB_VAT(sb));
1614
        if (UDF_SB_NUMPARTS(sb))
1615
        {
1616
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1617
                        iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1618
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1619
                        iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1620
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1621
                {
1622
                        for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_uspace); i++)
1623
                        {
1624
                                if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i))
1625
                                        udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_uspace,i));
1626
                        }
1627
                        kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
1628
                }
1629
                if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1630
                {
1631
                        for (i=0; i<UDF_SB_BITMAP_NR_GROUPS(sb,UDF_SB_PARTITION(sb),s_fspace); i++)
1632
                        {
1633
                                if (UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i))
1634
                                        udf_release_data(UDF_SB_BITMAP(sb,UDF_SB_PARTITION(sb),s_fspace,i));
1635
                        }
1636
                        kfree(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
1637
                }
1638
                if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
1639
                {
1640
                        for (i=0; i<4; i++)
1641
                                udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
1642
                }
1643
        }
1644
#ifdef CONFIG_NLS
1645
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1646
                unload_nls(UDF_SB(sb)->s_nls_map);
1647
#endif
1648
        if (!(sb->s_flags & MS_RDONLY))
1649
                udf_close_lvid(sb);
1650
        udf_release_data(UDF_SB_LVIDBH(sb));
1651
        UDF_SB_FREE(sb);
1652
}
1653
 
1654
/*
1655
 * udf_stat_fs
1656
 *
1657
 * PURPOSE
1658
 *      Return info about the filesystem.
1659
 *
1660
 * DESCRIPTION
1661
 *      Called by sys_statfs()
1662
 *
1663
 * HISTORY
1664
 *      July 1, 1997 - Andrew E. Mileski
1665
 *      Written, tested, and released.
1666
 */
1667
static int
1668
udf_statfs(struct super_block *sb, struct statfs *buf)
1669
{
1670
        buf->f_type = UDF_SUPER_MAGIC;
1671
        buf->f_bsize = sb->s_blocksize;
1672
        buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
1673
        buf->f_bfree = udf_count_free(sb);
1674
        buf->f_bavail = buf->f_bfree;
1675
        buf->f_files = (UDF_SB_LVIDBH(sb) ?
1676
                (le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
1677
                le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree;
1678
        buf->f_ffree = buf->f_bfree;
1679
        /* __kernel_fsid_t f_fsid */
1680
        buf->f_namelen = UDF_NAME_LEN;
1681
 
1682
        return 0;
1683
}
1684
 
1685
static unsigned char udf_bitmap_lookup[16] = {
1686
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
1687
};
1688
 
1689
static unsigned int
1690
udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
1691
{
1692
        struct buffer_head *bh = NULL;
1693
        unsigned int accum = 0;
1694
        int index;
1695
        int block = 0, newblock;
1696
        lb_addr loc;
1697
        uint32_t bytes;
1698
        uint8_t value;
1699
        uint8_t *ptr;
1700
        uint16_t ident;
1701
        struct spaceBitmapDesc *bm;
1702
 
1703
        loc.logicalBlockNum = bitmap->s_extPosition;
1704
        loc.partitionReferenceNum = UDF_SB_PARTITION(sb);
1705
        bh = udf_read_ptagged(sb, loc, 0, &ident);
1706
 
1707
        if (!bh)
1708
        {
1709
                printk(KERN_ERR "udf: udf_count_free failed\n");
1710
                return 0;
1711
        }
1712
        else if (ident != TAG_IDENT_SBD)
1713
        {
1714
                udf_release_data(bh);
1715
                printk(KERN_ERR "udf: udf_count_free failed\n");
1716
                return 0;
1717
        }
1718
 
1719
        bm = (struct spaceBitmapDesc *)bh->b_data;
1720
        bytes = bm->numOfBytes;
1721
        index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
1722
        ptr = (uint8_t *)bh->b_data;
1723
 
1724
        while ( bytes > 0 )
1725
        {
1726
                while ((bytes > 0) && (index < sb->s_blocksize))
1727
                {
1728
                        value = ptr[index];
1729
                        accum += udf_bitmap_lookup[ value & 0x0f ];
1730
                        accum += udf_bitmap_lookup[ value >> 4 ];
1731
                        index++;
1732
                        bytes--;
1733
                }
1734
                if ( bytes )
1735
                {
1736
                        udf_release_data(bh);
1737
                        newblock = udf_get_lb_pblock(sb, loc, ++block);
1738
                        bh = udf_tread(sb, newblock);
1739
                        if (!bh)
1740
                        {
1741
                                udf_debug("read failed\n");
1742
                                return accum;
1743
                        }
1744
                        index = 0;
1745
                        ptr = (uint8_t *)bh->b_data;
1746
                }
1747
        }
1748
        udf_release_data(bh);
1749
        return accum;
1750
}
1751
 
1752
static unsigned int
1753
udf_count_free_table(struct super_block *sb, struct inode * table)
1754
{
1755
        unsigned int accum = 0;
1756
        uint32_t extoffset, elen;
1757
        lb_addr bloc, eloc;
1758
        int8_t etype;
1759
        struct buffer_head *bh = NULL;
1760
 
1761
        bloc = UDF_I_LOCATION(table);
1762
        extoffset = sizeof(struct unallocSpaceEntry);
1763
 
1764
        while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
1765
        {
1766
                accum += (elen >> table->i_sb->s_blocksize_bits);
1767
        }
1768
        udf_release_data(bh);
1769
        return accum;
1770
}
1771
 
1772
static unsigned int
1773
udf_count_free(struct super_block *sb)
1774
{
1775
        unsigned int accum = 0;
1776
 
1777
        if (UDF_SB_LVIDBH(sb))
1778
        {
1779
                if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
1780
                {
1781
                        accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
1782
 
1783
                        if (accum == 0xFFFFFFFF)
1784
                                accum = 0;
1785
                }
1786
        }
1787
 
1788
        if (accum)
1789
                return accum;
1790
 
1791
        if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
1792
        {
1793
                accum += udf_count_free_bitmap(sb,
1794
                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
1795
        }
1796
        if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
1797
        {
1798
                accum += udf_count_free_bitmap(sb,
1799
                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
1800
        }
1801
        if (accum)
1802
                return accum;
1803
 
1804
        if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
1805
        {
1806
                accum += udf_count_free_table(sb,
1807
                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
1808
        }
1809
        if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
1810
        {
1811
                accum += udf_count_free_table(sb,
1812
                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
1813
        }
1814
 
1815
        return accum;
1816
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.