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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [udf/] [super.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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