rock.c 19 KB

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