rock.c 18 KB

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