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