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