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 #include <linux/smp_lock.h> 12 13 #include "isofs.h" 14 #include "rock.h" 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 #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ 24 25 26 /* This is a way of ensuring that we have something in the system 27 use fields that is compatible with Rock Ridge */ 28 #define CHECK_SP(FAIL) \ 29 if(rr->u.SP.magic[0] != 0xbe) FAIL; \ 30 if(rr->u.SP.magic[1] != 0xef) FAIL; \ 31 ISOFS_SB(inode->i_sb)->s_rock_offset=rr->u.SP.skip; 32 /* We define a series of macros because each function must do exactly the 33 same thing in certain places. We use the macros to ensure that everything 34 is done correctly */ 35 36 #define CONTINUE_DECLS \ 37 int cont_extent = 0, cont_offset = 0, cont_size = 0; \ 38 void *buffer = NULL 39 40 #define CHECK_CE \ 41 {cont_extent = isonum_733(rr->u.CE.extent); \ 42 cont_offset = isonum_733(rr->u.CE.offset); \ 43 cont_size = isonum_733(rr->u.CE.size);} 44 45 #define SETUP_ROCK_RIDGE(DE,CHR,LEN) \ 46 {LEN= sizeof(struct iso_directory_record) + DE->name_len[0]; \ 47 if(LEN & 1) LEN++; \ 48 CHR = ((unsigned char *) DE) + LEN; \ 49 LEN = *((unsigned char *) DE) - LEN; \ 50 if (LEN<0) LEN=0; \ 51 if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \ 52 { \ 53 LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \ 54 CHR+=ISOFS_SB(inode->i_sb)->s_rock_offset; \ 55 if (LEN<0) LEN=0; \ 56 } \ 57 } 58 59 #define MAYBE_CONTINUE(LABEL,DEV) \ 60 {if (buffer) { kfree(buffer); buffer = NULL; } \ 61 if (cont_extent){ \ 62 int block, offset, offset1; \ 63 struct buffer_head * pbh; \ 64 buffer = kmalloc(cont_size,GFP_KERNEL); \ 65 if (!buffer) goto out; \ 66 block = cont_extent; \ 67 offset = cont_offset; \ 68 offset1 = 0; \ 69 pbh = sb_bread(DEV->i_sb, block); \ 70 if(pbh){ \ 71 if (offset > pbh->b_size || offset + cont_size > pbh->b_size){ \ 72 brelse(pbh); \ 73 goto out; \ 74 } \ 75 memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \ 76 brelse(pbh); \ 77 chr = (unsigned char *) buffer; \ 78 len = cont_size; \ 79 cont_extent = 0; \ 80 cont_size = 0; \ 81 cont_offset = 0; \ 82 goto LABEL; \ 83 } \ 84 printk("Unable to read rock-ridge attributes\n"); \ 85 }} 86 87 /* return length of name field; 0: not found, -1: to be ignored */ 88 int get_rock_ridge_filename(struct iso_directory_record * de, 89 char * retname, struct inode * inode) 90 { 91 int len; 92 unsigned char * chr; 93 CONTINUE_DECLS; 94 int retnamlen = 0, truncate=0; 95 96 if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; 97 *retname = 0; 98 99 SETUP_ROCK_RIDGE(de, chr, len); 100 repeat: 101 { 102 struct rock_ridge * rr; 103 int sig; 104 105 while (len > 2){ /* There may be one byte for padding somewhere */ 106 rr = (struct rock_ridge *) chr; 107 if (rr->len < 3) goto out; /* Something got screwed up here */ 108 sig = isonum_721(chr); 109 chr += rr->len; 110 len -= rr->len; 111 if (len < 0) goto out; /* corrupted isofs */ 112 113 switch(sig){ 114 case SIG('R','R'): 115 if((rr->u.RR.flags[0] & RR_NM) == 0) goto out; 116 break; 117 case SIG('S','P'): 118 CHECK_SP(goto out); 119 break; 120 case SIG('C','E'): 121 CHECK_CE; 122 break; 123 case SIG('N','M'): 124 if (truncate) break; 125 if (rr->len < 5) break; 126 /* 127 * If the flags are 2 or 4, this indicates '.' or '..'. 128 * We don't want to do anything with this, because it 129 * screws up the code that calls us. We don't really 130 * care anyways, since we can just use the non-RR 131 * name. 132 */ 133 if (rr->u.NM.flags & 6) { 134 break; 135 } 136 137 if (rr->u.NM.flags & ~1) { 138 printk("Unsupported NM flag settings (%d)\n",rr->u.NM.flags); 139 break; 140 } 141 if((strlen(retname) + rr->len - 5) >= 254) { 142 truncate = 1; 143 break; 144 } 145 strncat(retname, rr->u.NM.name, rr->len - 5); 146 retnamlen += rr->len - 5; 147 break; 148 case SIG('R','E'): 149 if (buffer) kfree(buffer); 150 return -1; 151 default: 152 break; 153 } 154 } 155 } 156 MAYBE_CONTINUE(repeat,inode); 157 if (buffer) kfree(buffer); 158 return retnamlen; /* If 0, this file did not have a NM field */ 159 out: 160 if(buffer) kfree(buffer); 161 return 0; 162 } 163 164 static int 165 parse_rock_ridge_inode_internal(struct iso_directory_record *de, 166 struct inode *inode, int regard_xa) 167 { 168 int len; 169 unsigned char * chr; 170 int symlink_len = 0; 171 CONTINUE_DECLS; 172 173 if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; 174 175 SETUP_ROCK_RIDGE(de, chr, len); 176 if (regard_xa) 177 { 178 chr+=14; 179 len-=14; 180 if (len<0) len=0; 181 } 182 183 repeat: 184 { 185 int cnt, sig; 186 struct inode * reloc; 187 struct rock_ridge * rr; 188 int rootflag; 189 190 while (len > 2){ /* There may be one byte for padding somewhere */ 191 rr = (struct rock_ridge *) chr; 192 if (rr->len < 3) goto out; /* Something got screwed up here */ 193 sig = isonum_721(chr); 194 chr += rr->len; 195 len -= rr->len; 196 if (len < 0) goto out; /* corrupted isofs */ 197 198 switch(sig){ 199 #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ 200 case SIG('R','R'): 201 if((rr->u.RR.flags[0] & 202 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out; 203 break; 204 #endif 205 case SIG('S','P'): 206 CHECK_SP(goto out); 207 break; 208 case SIG('C','E'): 209 CHECK_CE; 210 break; 211 case SIG('E','R'): 212 ISOFS_SB(inode->i_sb)->s_rock = 1; 213 printk(KERN_DEBUG "ISO 9660 Extensions: "); 214 { int p; 215 for(p=0;p<rr->u.ER.len_id;p++) printk("%c",rr->u.ER.data[p]); 216 } 217 printk("\n"); 218 break; 219 case SIG('P','X'): 220 inode->i_mode = isonum_733(rr->u.PX.mode); 221 inode->i_nlink = isonum_733(rr->u.PX.n_links); 222 inode->i_uid = isonum_733(rr->u.PX.uid); 223 inode->i_gid = isonum_733(rr->u.PX.gid); 224 break; 225 case SIG('P','N'): 226 { int high, low; 227 high = isonum_733(rr->u.PN.dev_high); 228 low = isonum_733(rr->u.PN.dev_low); 229 /* 230 * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, 231 * then the high field is unused, and the device number is completely 232 * stored in the low field. Some writers may ignore this subtlety, 233 * and as a result we test to see if the entire device number is 234 * stored in the low field, and use that. 235 */ 236 if((low & ~0xff) && high == 0) { 237 inode->i_rdev = MKDEV(low >> 8, low & 0xff); 238 } else { 239 inode->i_rdev = MKDEV(high, low); 240 } 241 } 242 break; 243 case SIG('T','F'): 244 /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. 245 Try to handle this correctly for either case. */ 246 cnt = 0; /* Rock ridge never appears on a High Sierra disk */ 247 if(rr->u.TF.flags & TF_CREATE) { 248 inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 249 inode->i_ctime.tv_nsec = 0; 250 } 251 if(rr->u.TF.flags & TF_MODIFY) { 252 inode->i_mtime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 253 inode->i_mtime.tv_nsec = 0; 254 } 255 if(rr->u.TF.flags & TF_ACCESS) { 256 inode->i_atime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 257 inode->i_atime.tv_nsec = 0; 258 } 259 if(rr->u.TF.flags & TF_ATTRIBUTES) { 260 inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 261 inode->i_ctime.tv_nsec = 0; 262 } 263 break; 264 case SIG('S','L'): 265 {int slen; 266 struct SL_component * slp; 267 struct SL_component * oldslp; 268 slen = rr->len - 5; 269 slp = &rr->u.SL.link; 270 inode->i_size = symlink_len; 271 while (slen > 1){ 272 rootflag = 0; 273 switch(slp->flags &~1){ 274 case 0: 275 inode->i_size += slp->len; 276 break; 277 case 2: 278 inode->i_size += 1; 279 break; 280 case 4: 281 inode->i_size += 2; 282 break; 283 case 8: 284 rootflag = 1; 285 inode->i_size += 1; 286 break; 287 default: 288 printk("Symlink component flag not implemented\n"); 289 } 290 slen -= slp->len + 2; 291 oldslp = slp; 292 slp = (struct SL_component *) (((char *) slp) + slp->len + 2); 293 294 if(slen < 2) { 295 if( ((rr->u.SL.flags & 1) != 0) 296 && ((oldslp->flags & 1) == 0) ) inode->i_size += 1; 297 break; 298 } 299 300 /* 301 * If this component record isn't continued, then append a '/'. 302 */ 303 if (!rootflag && (oldslp->flags & 1) == 0) 304 inode->i_size += 1; 305 } 306 } 307 symlink_len = inode->i_size; 308 break; 309 case SIG('R','E'): 310 printk(KERN_WARNING "Attempt to read inode for relocated directory\n"); 311 goto out; 312 case SIG('C','L'): 313 ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location); 314 reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0); 315 if (!reloc) 316 goto out; 317 inode->i_mode = reloc->i_mode; 318 inode->i_nlink = reloc->i_nlink; 319 inode->i_uid = reloc->i_uid; 320 inode->i_gid = reloc->i_gid; 321 inode->i_rdev = reloc->i_rdev; 322 inode->i_size = reloc->i_size; 323 inode->i_blocks = reloc->i_blocks; 324 inode->i_atime = reloc->i_atime; 325 inode->i_ctime = reloc->i_ctime; 326 inode->i_mtime = reloc->i_mtime; 327 iput(reloc); 328 break; 329 #ifdef CONFIG_ZISOFS 330 case SIG('Z','F'): 331 if ( !ISOFS_SB(inode->i_sb)->s_nocompress ) { 332 int algo; 333 algo = isonum_721(rr->u.ZF.algorithm); 334 if ( algo == SIG('p','z') ) { 335 int block_shift = isonum_711(&rr->u.ZF.parms[1]); 336 if ( block_shift < PAGE_CACHE_SHIFT || block_shift > 17 ) { 337 printk(KERN_WARNING "isofs: Can't handle ZF block size of 2^%d\n", block_shift); 338 } else { 339 /* Note: we don't change i_blocks here */ 340 ISOFS_I(inode)->i_file_format = isofs_file_compressed; 341 /* Parameters to compression algorithm (header size, block size) */ 342 ISOFS_I(inode)->i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]); 343 ISOFS_I(inode)->i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]); 344 inode->i_size = isonum_733(rr->u.ZF.real_size); 345 } 346 } else { 347 printk(KERN_WARNING "isofs: Unknown ZF compression algorithm: %c%c\n", 348 rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]); 349 } 350 } 351 break; 352 #endif 353 default: 354 break; 355 } 356 } 357 } 358 MAYBE_CONTINUE(repeat,inode); 359 out: 360 if(buffer) kfree(buffer); 361 return 0; 362 } 363 364 static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) 365 { 366 int slen; 367 int rootflag; 368 struct SL_component *oldslp; 369 struct SL_component *slp; 370 slen = rr->len - 5; 371 slp = &rr->u.SL.link; 372 while (slen > 1) { 373 rootflag = 0; 374 switch (slp->flags & ~1) { 375 case 0: 376 if (slp->len > plimit - rpnt) 377 return NULL; 378 memcpy(rpnt, slp->text, slp->len); 379 rpnt+=slp->len; 380 break; 381 case 2: 382 if (rpnt >= plimit) 383 return NULL; 384 *rpnt++='.'; 385 break; 386 case 4: 387 if (2 > plimit - rpnt) 388 return NULL; 389 *rpnt++='.'; 390 *rpnt++='.'; 391 break; 392 case 8: 393 if (rpnt >= plimit) 394 return NULL; 395 rootflag = 1; 396 *rpnt++='/'; 397 break; 398 default: 399 printk("Symlink component flag not implemented (%d)\n", 400 slp->flags); 401 } 402 slen -= slp->len + 2; 403 oldslp = slp; 404 slp = (struct SL_component *) ((char *) slp + slp->len + 2); 405 406 if (slen < 2) { 407 /* 408 * If there is another SL record, and this component 409 * record isn't continued, then add a slash. 410 */ 411 if ((!rootflag) && (rr->u.SL.flags & 1) && 412 !(oldslp->flags & 1)) { 413 if (rpnt >= plimit) 414 return NULL; 415 *rpnt++='/'; 416 } 417 break; 418 } 419 420 /* 421 * If this component record isn't continued, then append a '/'. 422 */ 423 if (!rootflag && !(oldslp->flags & 1)) { 424 if (rpnt >= plimit) 425 return NULL; 426 *rpnt++='/'; 427 } 428 } 429 return rpnt; 430 } 431 432 int parse_rock_ridge_inode(struct iso_directory_record * de, 433 struct inode * inode) 434 { 435 int result=parse_rock_ridge_inode_internal(de,inode,0); 436 /* if rockridge flag was reset and we didn't look for attributes 437 * behind eventual XA attributes, have a look there */ 438 if ((ISOFS_SB(inode->i_sb)->s_rock_offset==-1) 439 &&(ISOFS_SB(inode->i_sb)->s_rock==2)) 440 { 441 result=parse_rock_ridge_inode_internal(de,inode,14); 442 } 443 return result; 444 } 445 446 /* readpage() for symlinks: reads symlink contents into the page and either 447 makes it uptodate and returns 0 or returns error (-EIO) */ 448 449 static int rock_ridge_symlink_readpage(struct file *file, struct page *page) 450 { 451 struct inode *inode = page->mapping->host; 452 struct iso_inode_info *ei = ISOFS_I(inode); 453 char *link = kmap(page); 454 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); 455 struct buffer_head *bh; 456 char *rpnt = link; 457 unsigned char *pnt; 458 struct iso_directory_record *raw_inode; 459 CONTINUE_DECLS; 460 unsigned long block, offset; 461 int sig; 462 int len; 463 unsigned char *chr; 464 struct rock_ridge *rr; 465 466 if (!ISOFS_SB(inode->i_sb)->s_rock) 467 goto error; 468 469 block = ei->i_iget5_block; 470 lock_kernel(); 471 bh = sb_bread(inode->i_sb, block); 472 if (!bh) 473 goto out_noread; 474 475 offset = ei->i_iget5_offset; 476 pnt = (unsigned char *) bh->b_data + offset; 477 478 raw_inode = (struct iso_directory_record *) pnt; 479 480 /* 481 * If we go past the end of the buffer, there is some sort of error. 482 */ 483 if (offset + *pnt > bufsize) 484 goto out_bad_span; 485 486 /* Now test for possible Rock Ridge extensions which will override 487 some of these numbers in the inode structure. */ 488 489 SETUP_ROCK_RIDGE(raw_inode, chr, len); 490 491 repeat: 492 while (len > 2) { /* There may be one byte for padding somewhere */ 493 rr = (struct rock_ridge *) chr; 494 if (rr->len < 3) 495 goto out; /* Something got screwed up here */ 496 sig = isonum_721(chr); 497 chr += rr->len; 498 len -= rr->len; 499 if (len < 0) 500 goto out; /* corrupted isofs */ 501 502 switch (sig) { 503 case SIG('R', 'R'): 504 if ((rr->u.RR.flags[0] & RR_SL) == 0) 505 goto out; 506 break; 507 case SIG('S', 'P'): 508 CHECK_SP(goto out); 509 break; 510 case SIG('S', 'L'): 511 rpnt = get_symlink_chunk(rpnt, rr, 512 link + (PAGE_SIZE - 1)); 513 if (rpnt == NULL) 514 goto out; 515 break; 516 case SIG('C', 'E'): 517 /* This tells is if there is a continuation record */ 518 CHECK_CE; 519 default: 520 break; 521 } 522 } 523 MAYBE_CONTINUE(repeat, inode); 524 if (buffer) 525 kfree(buffer); 526 527 if (rpnt == link) 528 goto fail; 529 brelse(bh); 530 *rpnt = '\0'; 531 unlock_kernel(); 532 SetPageUptodate(page); 533 kunmap(page); 534 unlock_page(page); 535 return 0; 536 537 /* error exit from macro */ 538 out: 539 if (buffer) 540 kfree(buffer); 541 goto fail; 542 out_noread: 543 printk("unable to read i-node block"); 544 goto fail; 545 out_bad_span: 546 printk("symlink spans iso9660 blocks\n"); 547 fail: 548 brelse(bh); 549 unlock_kernel(); 550 error: 551 SetPageError(page); 552 kunmap(page); 553 unlock_page(page); 554 return -EIO; 555 } 556 557 struct address_space_operations isofs_symlink_aops = { 558 .readpage = rock_ridge_symlink_readpage 559 }; 560