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