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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [isofs/] [rock.c] - Blame information for rev 78

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

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  linux/fs/isofs/rock.c
3
 *
4
 *  (C) 1992, 1993  Eric Youngdale
5
 *
6
 *  Rock Ridge Extensions to iso9660
7
 */
8
 
9
#include <linux/slab.h>
10
#include <linux/pagemap.h>
11
#include <linux/smp_lock.h>
12
 
13
#include "isofs.h"
14
#include "rock.h"
15
 
16
/*
17
 * These functions are designed to read the system areas of a directory record
18
 * and extract relevant information.  There are different functions provided
19
 * depending upon what information we need at the time.  One function fills
20
 * out an inode structure, a second one extracts a filename, a third one
21
 * returns a symbolic link name, and a fourth one returns the extent number
22
 * for the file.
23
 */
24
 
25
#define SIG(A,B) ((A) | ((B) << 8))     /* isonum_721() */
26
 
27
struct rock_state {
28
        void *buffer;
29
        unsigned char *chr;
30
        int len;
31
        int cont_size;
32
        int cont_extent;
33
        int cont_offset;
34
        struct inode *inode;
35
};
36
 
37
/*
38
 * This is a way of ensuring that we have something in the system
39
 * use fields that is compatible with Rock Ridge.  Return zero on success.
40
 */
41
 
42
static int check_sp(struct rock_ridge *rr, struct inode *inode)
43
{
44
        if (rr->u.SP.magic[0] != 0xbe)
45
                return -1;
46
        if (rr->u.SP.magic[1] != 0xef)
47
                return -1;
48
        ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip;
49
        return 0;
50
}
51
 
52
static void setup_rock_ridge(struct iso_directory_record *de,
53
                        struct inode *inode, struct rock_state *rs)
54
{
55
        rs->len = sizeof(struct iso_directory_record) + de->name_len[0];
56
        if (rs->len & 1)
57
                (rs->len)++;
58
        rs->chr = (unsigned char *)de + rs->len;
59
        rs->len = *((unsigned char *)de) - rs->len;
60
        if (rs->len < 0)
61
                rs->len = 0;
62
 
63
        if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) {
64
                rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset;
65
                rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset;
66
                if (rs->len < 0)
67
                        rs->len = 0;
68
        }
69
}
70
 
71
static void init_rock_state(struct rock_state *rs, struct inode *inode)
72
{
73
        memset(rs, 0, sizeof(*rs));
74
        rs->inode = inode;
75
}
76
 
77
/*
78
 * Returns 0 if the caller should continue scanning, 1 if the scan must end
79
 * and -ve on error.
80
 */
81
static int rock_continue(struct rock_state *rs)
82
{
83
        int ret = 1;
84
        int blocksize = 1 << rs->inode->i_blkbits;
85
        const int min_de_size = offsetof(struct rock_ridge, u);
86
 
87
        kfree(rs->buffer);
88
        rs->buffer = NULL;
89
 
90
        if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
91
            (unsigned)rs->cont_size > blocksize ||
92
            (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
93
                printk(KERN_NOTICE "rock: corrupted directory entry. "
94
                        "extent=%d, offset=%d, size=%d\n",
95
                        rs->cont_extent, rs->cont_offset, rs->cont_size);
96
                ret = -EIO;
97
                goto out;
98
        }
99
 
100
        if (rs->cont_extent) {
101
                struct buffer_head *bh;
102
 
103
                rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL);
104
                if (!rs->buffer) {
105
                        ret = -ENOMEM;
106
                        goto out;
107
                }
108
                ret = -EIO;
109
                bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
110
                if (bh) {
111
                        memcpy(rs->buffer, bh->b_data + rs->cont_offset,
112
                                        rs->cont_size);
113
                        put_bh(bh);
114
                        rs->chr = rs->buffer;
115
                        rs->len = rs->cont_size;
116
                        rs->cont_extent = 0;
117
                        rs->cont_size = 0;
118
                        rs->cont_offset = 0;
119
                        return 0;
120
                }
121
                printk("Unable to read rock-ridge attributes\n");
122
        }
123
out:
124
        kfree(rs->buffer);
125
        rs->buffer = NULL;
126
        return ret;
127
}
128
 
129
/*
130
 * We think there's a record of type `sig' at rs->chr.  Parse the signature
131
 * and make sure that there's really room for a record of that type.
132
 */
133
static int rock_check_overflow(struct rock_state *rs, int sig)
134
{
135
        int len;
136
 
137
        switch (sig) {
138
        case SIG('S', 'P'):
139
                len = sizeof(struct SU_SP_s);
140
                break;
141
        case SIG('C', 'E'):
142
                len = sizeof(struct SU_CE_s);
143
                break;
144
        case SIG('E', 'R'):
145
                len = sizeof(struct SU_ER_s);
146
                break;
147
        case SIG('R', 'R'):
148
                len = sizeof(struct RR_RR_s);
149
                break;
150
        case SIG('P', 'X'):
151
                len = sizeof(struct RR_PX_s);
152
                break;
153
        case SIG('P', 'N'):
154
                len = sizeof(struct RR_PN_s);
155
                break;
156
        case SIG('S', 'L'):
157
                len = sizeof(struct RR_SL_s);
158
                break;
159
        case SIG('N', 'M'):
160
                len = sizeof(struct RR_NM_s);
161
                break;
162
        case SIG('C', 'L'):
163
                len = sizeof(struct RR_CL_s);
164
                break;
165
        case SIG('P', 'L'):
166
                len = sizeof(struct RR_PL_s);
167
                break;
168
        case SIG('T', 'F'):
169
                len = sizeof(struct RR_TF_s);
170
                break;
171
        case SIG('Z', 'F'):
172
                len = sizeof(struct RR_ZF_s);
173
                break;
174
        default:
175
                len = 0;
176
                break;
177
        }
178
        len += offsetof(struct rock_ridge, u);
179
        if (len > rs->len) {
180
                printk(KERN_NOTICE "rock: directory entry would overflow "
181
                                "storage\n");
182
                printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n",
183
                                sig, len, rs->len);
184
                return -EIO;
185
        }
186
        return 0;
187
}
188
 
189
/*
190
 * return length of name field; 0: not found, -1: to be ignored
191
 */
192
int get_rock_ridge_filename(struct iso_directory_record *de,
193
                            char *retname, struct inode *inode)
194
{
195
        struct rock_state rs;
196
        struct rock_ridge *rr;
197
        int sig;
198
        int retnamlen = 0;
199
        int truncate = 0;
200
        int ret = 0;
201
 
202
        if (!ISOFS_SB(inode->i_sb)->s_rock)
203
                return 0;
204
        *retname = 0;
205
 
206
        init_rock_state(&rs, inode);
207
        setup_rock_ridge(de, inode, &rs);
208
repeat:
209
 
210
        while (rs.len > 2) { /* There may be one byte for padding somewhere */
211
                rr = (struct rock_ridge *)rs.chr;
212
                if (rr->len < 3)
213
                        goto out;       /* Something got screwed up here */
214
                sig = isonum_721(rs.chr);
215
                if (rock_check_overflow(&rs, sig))
216
                        goto eio;
217
                rs.chr += rr->len;
218
                rs.len -= rr->len;
219
                if (rs.len < 0)
220
                        goto eio;       /* corrupted isofs */
221
 
222
                switch (sig) {
223
                case SIG('R', 'R'):
224
                        if ((rr->u.RR.flags[0] & RR_NM) == 0)
225
                                goto out;
226
                        break;
227
                case SIG('S', 'P'):
228
                        if (check_sp(rr, inode))
229
                                goto out;
230
                        break;
231
                case SIG('C', 'E'):
232
                        rs.cont_extent = isonum_733(rr->u.CE.extent);
233
                        rs.cont_offset = isonum_733(rr->u.CE.offset);
234
                        rs.cont_size = isonum_733(rr->u.CE.size);
235
                        break;
236
                case SIG('N', 'M'):
237
                        if (truncate)
238
                                break;
239
                        if (rr->len < 5)
240
                                break;
241
                        /*
242
                         * If the flags are 2 or 4, this indicates '.' or '..'.
243
                         * We don't want to do anything with this, because it
244
                         * screws up the code that calls us.  We don't really
245
                         * care anyways, since we can just use the non-RR
246
                         * name.
247
                         */
248
                        if (rr->u.NM.flags & 6)
249
                                break;
250
 
251
                        if (rr->u.NM.flags & ~1) {
252
                                printk("Unsupported NM flag settings (%d)\n",
253
                                        rr->u.NM.flags);
254
                                break;
255
                        }
256
                        if ((strlen(retname) + rr->len - 5) >= 254) {
257
                                truncate = 1;
258
                                break;
259
                        }
260
                        strncat(retname, rr->u.NM.name, rr->len - 5);
261
                        retnamlen += rr->len - 5;
262
                        break;
263
                case SIG('R', 'E'):
264
                        kfree(rs.buffer);
265
                        return -1;
266
                default:
267
                        break;
268
                }
269
        }
270
        ret = rock_continue(&rs);
271
        if (ret == 0)
272
                goto repeat;
273
        if (ret == 1)
274
                return retnamlen; /* If 0, this file did not have a NM field */
275
out:
276
        kfree(rs.buffer);
277
        return ret;
278
eio:
279
        ret = -EIO;
280
        goto out;
281
}
282
 
283
static int
284
parse_rock_ridge_inode_internal(struct iso_directory_record *de,
285
                                struct inode *inode, int regard_xa)
286
{
287
        int symlink_len = 0;
288
        int cnt, sig;
289
        struct inode *reloc;
290
        struct rock_ridge *rr;
291
        int rootflag;
292
        struct rock_state rs;
293
        int ret = 0;
294
 
295
        if (!ISOFS_SB(inode->i_sb)->s_rock)
296
                return 0;
297
 
298
        init_rock_state(&rs, inode);
299
        setup_rock_ridge(de, inode, &rs);
300
        if (regard_xa) {
301
                rs.chr += 14;
302
                rs.len -= 14;
303
                if (rs.len < 0)
304
                        rs.len = 0;
305
        }
306
 
307
repeat:
308
        while (rs.len > 2) { /* There may be one byte for padding somewhere */
309
                rr = (struct rock_ridge *)rs.chr;
310
                if (rr->len < 3)
311
                        goto out;       /* Something got screwed up here */
312
                sig = isonum_721(rs.chr);
313
                if (rock_check_overflow(&rs, sig))
314
                        goto eio;
315
                rs.chr += rr->len;
316
                rs.len -= rr->len;
317
                if (rs.len < 0)
318
                        goto eio;       /* corrupted isofs */
319
 
320
                switch (sig) {
321
#ifndef CONFIG_ZISOFS           /* No flag for SF or ZF */
322
                case SIG('R', 'R'):
323
                        if ((rr->u.RR.flags[0] &
324
                             (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
325
                                goto out;
326
                        break;
327
#endif
328
                case SIG('S', 'P'):
329
                        if (check_sp(rr, inode))
330
                                goto out;
331
                        break;
332
                case SIG('C', 'E'):
333
                        rs.cont_extent = isonum_733(rr->u.CE.extent);
334
                        rs.cont_offset = isonum_733(rr->u.CE.offset);
335
                        rs.cont_size = isonum_733(rr->u.CE.size);
336
                        break;
337
                case SIG('E', 'R'):
338
                        ISOFS_SB(inode->i_sb)->s_rock = 1;
339
                        printk(KERN_DEBUG "ISO 9660 Extensions: ");
340
                        {
341
                                int p;
342
                                for (p = 0; p < rr->u.ER.len_id; p++)
343
                                        printk("%c", rr->u.ER.data[p]);
344
                        }
345
                        printk("\n");
346
                        break;
347
                case SIG('P', 'X'):
348
                        inode->i_mode = isonum_733(rr->u.PX.mode);
349
                        inode->i_nlink = isonum_733(rr->u.PX.n_links);
350
                        inode->i_uid = isonum_733(rr->u.PX.uid);
351
                        inode->i_gid = isonum_733(rr->u.PX.gid);
352
                        break;
353
                case SIG('P', 'N'):
354
                        {
355
                                int high, low;
356
                                high = isonum_733(rr->u.PN.dev_high);
357
                                low = isonum_733(rr->u.PN.dev_low);
358
                                /*
359
                                 * The Rock Ridge standard specifies that if
360
                                 * sizeof(dev_t) <= 4, then the high field is
361
                                 * unused, and the device number is completely
362
                                 * stored in the low field.  Some writers may
363
                                 * ignore this subtlety,
364
                                 * and as a result we test to see if the entire
365
                                 * device number is
366
                                 * stored in the low field, and use that.
367
                                 */
368
                                if ((low & ~0xff) && high == 0) {
369
                                        inode->i_rdev =
370
                                            MKDEV(low >> 8, low & 0xff);
371
                                } else {
372
                                        inode->i_rdev =
373
                                            MKDEV(high, low);
374
                                }
375
                        }
376
                        break;
377
                case SIG('T', 'F'):
378
                        /*
379
                         * Some RRIP writers incorrectly place ctime in the
380
                         * TF_CREATE field. Try to handle this correctly for
381
                         * either case.
382
                         */
383
                        /* Rock ridge never appears on a High Sierra disk */
384
                        cnt = 0;
385
                        if (rr->u.TF.flags & TF_CREATE) {
386
                                inode->i_ctime.tv_sec =
387
                                    iso_date(rr->u.TF.times[cnt++].time,
388
                                             0);
389
                                inode->i_ctime.tv_nsec = 0;
390
                        }
391
                        if (rr->u.TF.flags & TF_MODIFY) {
392
                                inode->i_mtime.tv_sec =
393
                                    iso_date(rr->u.TF.times[cnt++].time,
394
                                             0);
395
                                inode->i_mtime.tv_nsec = 0;
396
                        }
397
                        if (rr->u.TF.flags & TF_ACCESS) {
398
                                inode->i_atime.tv_sec =
399
                                    iso_date(rr->u.TF.times[cnt++].time,
400
                                             0);
401
                                inode->i_atime.tv_nsec = 0;
402
                        }
403
                        if (rr->u.TF.flags & TF_ATTRIBUTES) {
404
                                inode->i_ctime.tv_sec =
405
                                    iso_date(rr->u.TF.times[cnt++].time,
406
                                             0);
407
                                inode->i_ctime.tv_nsec = 0;
408
                        }
409
                        break;
410
                case SIG('S', 'L'):
411
                        {
412
                                int slen;
413
                                struct SL_component *slp;
414
                                struct SL_component *oldslp;
415
                                slen = rr->len - 5;
416
                                slp = &rr->u.SL.link;
417
                                inode->i_size = symlink_len;
418
                                while (slen > 1) {
419
                                        rootflag = 0;
420
                                        switch (slp->flags & ~1) {
421
                                        case 0:
422
                                                inode->i_size +=
423
                                                    slp->len;
424
                                                break;
425
                                        case 2:
426
                                                inode->i_size += 1;
427
                                                break;
428
                                        case 4:
429
                                                inode->i_size += 2;
430
                                                break;
431
                                        case 8:
432
                                                rootflag = 1;
433
                                                inode->i_size += 1;
434
                                                break;
435
                                        default:
436
                                                printk("Symlink component flag "
437
                                                        "not implemented\n");
438
                                        }
439
                                        slen -= slp->len + 2;
440
                                        oldslp = slp;
441
                                        slp = (struct SL_component *)
442
                                                (((char *)slp) + slp->len + 2);
443
 
444
                                        if (slen < 2) {
445
                                                if (((rr->u.SL.
446
                                                      flags & 1) != 0)
447
                                                    &&
448
                                                    ((oldslp->
449
                                                      flags & 1) == 0))
450
                                                        inode->i_size +=
451
                                                            1;
452
                                                break;
453
                                        }
454
 
455
                                        /*
456
                                         * If this component record isn't
457
                                         * continued, then append a '/'.
458
                                         */
459
                                        if (!rootflag
460
                                            && (oldslp->flags & 1) == 0)
461
                                                inode->i_size += 1;
462
                                }
463
                        }
464
                        symlink_len = inode->i_size;
465
                        break;
466
                case SIG('R', 'E'):
467
                        printk(KERN_WARNING "Attempt to read inode for "
468
                                        "relocated directory\n");
469
                        goto out;
470
                case SIG('C', 'L'):
471
                        ISOFS_I(inode)->i_first_extent =
472
                            isonum_733(rr->u.CL.location);
473
                        reloc =
474
                            isofs_iget(inode->i_sb,
475
                                       ISOFS_I(inode)->i_first_extent,
476
                                       0);
477
                        if (!reloc)
478
                                goto out;
479
                        inode->i_mode = reloc->i_mode;
480
                        inode->i_nlink = reloc->i_nlink;
481
                        inode->i_uid = reloc->i_uid;
482
                        inode->i_gid = reloc->i_gid;
483
                        inode->i_rdev = reloc->i_rdev;
484
                        inode->i_size = reloc->i_size;
485
                        inode->i_blocks = reloc->i_blocks;
486
                        inode->i_atime = reloc->i_atime;
487
                        inode->i_ctime = reloc->i_ctime;
488
                        inode->i_mtime = reloc->i_mtime;
489
                        iput(reloc);
490
                        break;
491
#ifdef CONFIG_ZISOFS
492
                case SIG('Z', 'F'): {
493
                        int algo;
494
 
495
                        if (ISOFS_SB(inode->i_sb)->s_nocompress)
496
                                break;
497
                        algo = isonum_721(rr->u.ZF.algorithm);
498
                        if (algo == SIG('p', 'z')) {
499
                                int block_shift =
500
                                        isonum_711(&rr->u.ZF.parms[1]);
501
                                if (block_shift < PAGE_CACHE_SHIFT
502
                                                || block_shift > 17) {
503
                                        printk(KERN_WARNING "isofs: "
504
                                                "Can't handle ZF block "
505
                                                "size of 2^%d\n",
506
                                                block_shift);
507
                                } else {
508
                                        /*
509
                                         * Note: we don't change
510
                                         * i_blocks here
511
                                         */
512
                                        ISOFS_I(inode)->i_file_format =
513
                                                isofs_file_compressed;
514
                                        /*
515
                                         * Parameters to compression
516
                                         * algorithm (header size,
517
                                         * block size)
518
                                         */
519
                                        ISOFS_I(inode)->i_format_parm[0] =
520
                                                isonum_711(&rr->u.ZF.parms[0]);
521
                                        ISOFS_I(inode)->i_format_parm[1] =
522
                                                isonum_711(&rr->u.ZF.parms[1]);
523
                                        inode->i_size =
524
                                            isonum_733(rr->u.ZF.
525
                                                       real_size);
526
                                }
527
                        } else {
528
                                printk(KERN_WARNING
529
                                       "isofs: Unknown ZF compression "
530
                                                "algorithm: %c%c\n",
531
                                       rr->u.ZF.algorithm[0],
532
                                       rr->u.ZF.algorithm[1]);
533
                        }
534
                        break;
535
                }
536
#endif
537
                default:
538
                        break;
539
                }
540
        }
541
        ret = rock_continue(&rs);
542
        if (ret == 0)
543
                goto repeat;
544
        if (ret == 1)
545
                ret = 0;
546
out:
547
        kfree(rs.buffer);
548
        return ret;
549
eio:
550
        ret = -EIO;
551
        goto out;
552
}
553
 
554
static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
555
{
556
        int slen;
557
        int rootflag;
558
        struct SL_component *oldslp;
559
        struct SL_component *slp;
560
        slen = rr->len - 5;
561
        slp = &rr->u.SL.link;
562
        while (slen > 1) {
563
                rootflag = 0;
564
                switch (slp->flags & ~1) {
565
                case 0:
566
                        if (slp->len > plimit - rpnt)
567
                                return NULL;
568
                        memcpy(rpnt, slp->text, slp->len);
569
                        rpnt += slp->len;
570
                        break;
571
                case 2:
572
                        if (rpnt >= plimit)
573
                                return NULL;
574
                        *rpnt++ = '.';
575
                        break;
576
                case 4:
577
                        if (2 > plimit - rpnt)
578
                                return NULL;
579
                        *rpnt++ = '.';
580
                        *rpnt++ = '.';
581
                        break;
582
                case 8:
583
                        if (rpnt >= plimit)
584
                                return NULL;
585
                        rootflag = 1;
586
                        *rpnt++ = '/';
587
                        break;
588
                default:
589
                        printk("Symlink component flag not implemented (%d)\n",
590
                               slp->flags);
591
                }
592
                slen -= slp->len + 2;
593
                oldslp = slp;
594
                slp = (struct SL_component *)((char *)slp + slp->len + 2);
595
 
596
                if (slen < 2) {
597
                        /*
598
                         * If there is another SL record, and this component
599
                         * record isn't continued, then add a slash.
600
                         */
601
                        if ((!rootflag) && (rr->u.SL.flags & 1) &&
602
                            !(oldslp->flags & 1)) {
603
                                if (rpnt >= plimit)
604
                                        return NULL;
605
                                *rpnt++ = '/';
606
                        }
607
                        break;
608
                }
609
 
610
                /*
611
                 * If this component record isn't continued, then append a '/'.
612
                 */
613
                if (!rootflag && !(oldslp->flags & 1)) {
614
                        if (rpnt >= plimit)
615
                                return NULL;
616
                        *rpnt++ = '/';
617
                }
618
        }
619
        return rpnt;
620
}
621
 
622
int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
623
{
624
        int result = parse_rock_ridge_inode_internal(de, inode, 0);
625
 
626
        /*
627
         * if rockridge flag was reset and we didn't look for attributes
628
         * behind eventual XA attributes, have a look there
629
         */
630
        if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
631
            && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
632
                result = parse_rock_ridge_inode_internal(de, inode, 14);
633
        }
634
        return result;
635
}
636
 
637
/*
638
 * readpage() for symlinks: reads symlink contents into the page and either
639
 * makes it uptodate and returns 0 or returns error (-EIO)
640
 */
641
static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
642
{
643
        struct inode *inode = page->mapping->host;
644
        struct iso_inode_info *ei = ISOFS_I(inode);
645
        char *link = kmap(page);
646
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
647
        struct buffer_head *bh;
648
        char *rpnt = link;
649
        unsigned char *pnt;
650
        struct iso_directory_record *raw_de;
651
        unsigned long block, offset;
652
        int sig;
653
        struct rock_ridge *rr;
654
        struct rock_state rs;
655
        int ret;
656
 
657
        if (!ISOFS_SB(inode->i_sb)->s_rock)
658
                goto error;
659
 
660
        init_rock_state(&rs, inode);
661
        block = ei->i_iget5_block;
662
        lock_kernel();
663
        bh = sb_bread(inode->i_sb, block);
664
        if (!bh)
665
                goto out_noread;
666
 
667
        offset = ei->i_iget5_offset;
668
        pnt = (unsigned char *)bh->b_data + offset;
669
 
670
        raw_de = (struct iso_directory_record *)pnt;
671
 
672
        /*
673
         * If we go past the end of the buffer, there is some sort of error.
674
         */
675
        if (offset + *pnt > bufsize)
676
                goto out_bad_span;
677
 
678
        /*
679
         * Now test for possible Rock Ridge extensions which will override
680
         * some of these numbers in the inode structure.
681
         */
682
 
683
        setup_rock_ridge(raw_de, inode, &rs);
684
 
685
repeat:
686
        while (rs.len > 2) { /* There may be one byte for padding somewhere */
687
                rr = (struct rock_ridge *)rs.chr;
688
                if (rr->len < 3)
689
                        goto out;       /* Something got screwed up here */
690
                sig = isonum_721(rs.chr);
691
                if (rock_check_overflow(&rs, sig))
692
                        goto out;
693
                rs.chr += rr->len;
694
                rs.len -= rr->len;
695
                if (rs.len < 0)
696
                        goto out;       /* corrupted isofs */
697
 
698
                switch (sig) {
699
                case SIG('R', 'R'):
700
                        if ((rr->u.RR.flags[0] & RR_SL) == 0)
701
                                goto out;
702
                        break;
703
                case SIG('S', 'P'):
704
                        if (check_sp(rr, inode))
705
                                goto out;
706
                        break;
707
                case SIG('S', 'L'):
708
                        rpnt = get_symlink_chunk(rpnt, rr,
709
                                                 link + (PAGE_SIZE - 1));
710
                        if (rpnt == NULL)
711
                                goto out;
712
                        break;
713
                case SIG('C', 'E'):
714
                        /* This tells is if there is a continuation record */
715
                        rs.cont_extent = isonum_733(rr->u.CE.extent);
716
                        rs.cont_offset = isonum_733(rr->u.CE.offset);
717
                        rs.cont_size = isonum_733(rr->u.CE.size);
718
                default:
719
                        break;
720
                }
721
        }
722
        ret = rock_continue(&rs);
723
        if (ret == 0)
724
                goto repeat;
725
        if (ret < 0)
726
                goto fail;
727
 
728
        if (rpnt == link)
729
                goto fail;
730
        brelse(bh);
731
        *rpnt = '\0';
732
        unlock_kernel();
733
        SetPageUptodate(page);
734
        kunmap(page);
735
        unlock_page(page);
736
        return 0;
737
 
738
        /* error exit from macro */
739
out:
740
        kfree(rs.buffer);
741
        goto fail;
742
out_noread:
743
        printk("unable to read i-node block");
744
        goto fail;
745
out_bad_span:
746
        printk("symlink spans iso9660 blocks\n");
747
fail:
748
        brelse(bh);
749
        unlock_kernel();
750
error:
751
        SetPageError(page);
752
        kunmap(page);
753
        unlock_page(page);
754
        return -EIO;
755
}
756
 
757
const struct address_space_operations isofs_symlink_aops = {
758
        .readpage = rock_ridge_symlink_readpage
759
};

powered by: WebSVN 2.1.0

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