aboutsummaryrefslogtreecommitdiffstats
path: root/fs/isofs/rock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/isofs/rock.c')
-rw-r--r--fs/isofs/rock.c571
1 files changed, 285 insertions, 286 deletions
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index bbc348f0189a..e981c040a49b 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -90,82 +90,78 @@ int get_rock_ridge_filename(struct iso_directory_record *de,
90 int len; 90 int len;
91 unsigned char *chr; 91 unsigned char *chr;
92 CONTINUE_DECLS; 92 CONTINUE_DECLS;
93 int retnamlen = 0, truncate = 0; 93 struct rock_ridge *rr;
94 int sig;
95 int retnamlen = 0;
96 int truncate = 0;
94 97
95 if (!ISOFS_SB(inode->i_sb)->s_rock) 98 if (!ISOFS_SB(inode->i_sb)->s_rock)
96 return 0; 99 return 0;
97 *retname = 0; 100 *retname = 0;
98 101
99 SETUP_ROCK_RIDGE(de, chr, len); 102 SETUP_ROCK_RIDGE(de, chr, len);
100 repeat: 103repeat:
101 { 104
102 struct rock_ridge *rr; 105 while (len > 2) { /* There may be one byte for padding somewhere */
103 int sig; 106 rr = (struct rock_ridge *)chr;
104 107 if (rr->len < 3)
105 while (len > 2) { /* There may be one byte for padding somewhere */ 108 goto out; /* Something got screwed up here */
106 rr = (struct rock_ridge *)chr; 109 sig = isonum_721(chr);
107 if (rr->len < 3) 110 chr += rr->len;
108 goto out; /* Something got screwed up here */ 111 len -= rr->len;
109 sig = isonum_721(chr); 112 if (len < 0)
110 chr += rr->len; 113 goto out; /* corrupted isofs */
111 len -= rr->len; 114
112 if (len < 0) 115 switch (sig) {
113 goto out; /* corrupted isofs */ 116 case SIG('R', 'R'):
114 117 if ((rr->u.RR.flags[0] & RR_NM) == 0)
115 switch (sig) { 118 goto out;
116 case SIG('R', 'R'): 119 break;
117 if ((rr->u.RR.flags[0] & RR_NM) == 0) 120 case SIG('S', 'P'):
118 goto out; 121 CHECK_SP(goto out);
122 break;
123 case SIG('C', 'E'):
124 CHECK_CE;
125 break;
126 case SIG('N', 'M'):
127 if (truncate)
119 break; 128 break;
120 case SIG('S', 'P'): 129 if (rr->len < 5)
121 CHECK_SP(goto out);
122 break; 130 break;
123 case SIG('C', 'E'): 131 /*
124 CHECK_CE; 132 * If the flags are 2 or 4, this indicates '.' or '..'.
133 * We don't want to do anything with this, because it
134 * screws up the code that calls us. We don't really
135 * care anyways, since we can just use the non-RR
136 * name.
137 */
138 if (rr->u.NM.flags & 6)
125 break; 139 break;
126 case SIG('N', 'M'):
127 if (truncate)
128 break;
129 if (rr->len < 5)
130 break;
131 /*
132 * If the flags are 2 or 4, this indicates '.' or '..'.
133 * We don't want to do anything with this, because it
134 * screws up the code that calls us. We don't really
135 * care anyways, since we can just use the non-RR
136 * name.
137 */
138 if (rr->u.NM.flags & 6) {
139 break;
140 }
141 140
142 if (rr->u.NM.flags & ~1) { 141 if (rr->u.NM.flags & ~1) {
143 printk 142 printk("Unsupported NM flag settings (%d)\n",
144 ("Unsupported NM flag settings (%d)\n", 143 rr->u.NM.flags);
145 rr->u.NM.flags);
146 break;
147 }
148 if ((strlen(retname) + rr->len - 5) >= 254) {
149 truncate = 1;
150 break;
151 }
152 strncat(retname, rr->u.NM.name, rr->len - 5);
153 retnamlen += rr->len - 5;
154 break; 144 break;
155 case SIG('R', 'E'): 145 }
156 if (buffer) 146 if ((strlen(retname) + rr->len - 5) >= 254) {
157 kfree(buffer); 147 truncate = 1;
158 return -1;
159 default:
160 break; 148 break;
161 } 149 }
150 strncat(retname, rr->u.NM.name, rr->len - 5);
151 retnamlen += rr->len - 5;
152 break;
153 case SIG('R', 'E'):
154 if (buffer)
155 kfree(buffer);
156 return -1;
157 default:
158 break;
162 } 159 }
163 } 160 }
164 MAYBE_CONTINUE(repeat, inode); 161 MAYBE_CONTINUE(repeat, inode);
165 if (buffer) 162 kfree(buffer);
166 kfree(buffer);
167 return retnamlen; /* If 0, this file did not have a NM field */ 163 return retnamlen; /* If 0, this file did not have a NM field */
168 out: 164out:
169 if (buffer) 165 if (buffer)
170 kfree(buffer); 166 kfree(buffer);
171 return 0; 167 return 0;
@@ -178,6 +174,11 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,
178 int len; 174 int len;
179 unsigned char *chr; 175 unsigned char *chr;
180 int symlink_len = 0; 176 int symlink_len = 0;
177 int cnt, sig;
178 struct inode *reloc;
179 struct rock_ridge *rr;
180 int rootflag;
181
181 CONTINUE_DECLS; 182 CONTINUE_DECLS;
182 183
183 if (!ISOFS_SB(inode->i_sb)->s_rock) 184 if (!ISOFS_SB(inode->i_sb)->s_rock)
@@ -191,238 +192,237 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de,
191 len = 0; 192 len = 0;
192 } 193 }
193 194
194 repeat: 195repeat:
195 { 196 while (len > 2) { /* There may be one byte for padding somewhere */
196 int cnt, sig; 197 rr = (struct rock_ridge *)chr;
197 struct inode *reloc; 198 if (rr->len < 3)
198 struct rock_ridge *rr; 199 goto out; /* Something got screwed up here */
199 int rootflag; 200 sig = isonum_721(chr);
200 201 chr += rr->len;
201 while (len > 2) { /* There may be one byte for padding somewhere */ 202 len -= rr->len;
202 rr = (struct rock_ridge *)chr; 203 if (len < 0)
203 if (rr->len < 3) 204 goto out; /* corrupted isofs */
204 goto out; /* Something got screwed up here */ 205
205 sig = isonum_721(chr); 206 switch (sig) {
206 chr += rr->len;
207 len -= rr->len;
208 if (len < 0)
209 goto out; /* corrupted isofs */
210
211 switch (sig) {
212#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ 207#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */
213 case SIG('R', 'R'): 208 case SIG('R', 'R'):
214 if ((rr->u.RR.flags[0] & 209 if ((rr->u.RR.flags[0] &
215 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) 210 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
216 goto out; 211 goto out;
217 break; 212 break;
218#endif 213#endif
219 case SIG('S', 'P'): 214 case SIG('S', 'P'):
220 CHECK_SP(goto out); 215 CHECK_SP(goto out);
221 break; 216 break;
222 case SIG('C', 'E'): 217 case SIG('C', 'E'):
223 CHECK_CE; 218 CHECK_CE;
224 break; 219 break;
225 case SIG('E', 'R'): 220 case SIG('E', 'R'):
226 ISOFS_SB(inode->i_sb)->s_rock = 1; 221 ISOFS_SB(inode->i_sb)->s_rock = 1;
227 printk(KERN_DEBUG "ISO 9660 Extensions: "); 222 printk(KERN_DEBUG "ISO 9660 Extensions: ");
228 { 223 {
229 int p; 224 int p;
230 for (p = 0; p < rr->u.ER.len_id; p++) 225 for (p = 0; p < rr->u.ER.len_id; p++)
231 printk("%c", rr->u.ER.data[p]); 226 printk("%c", rr->u.ER.data[p]);
227 }
228 printk("\n");
229 break;
230 case SIG('P', 'X'):
231 inode->i_mode = isonum_733(rr->u.PX.mode);
232 inode->i_nlink = isonum_733(rr->u.PX.n_links);
233 inode->i_uid = isonum_733(rr->u.PX.uid);
234 inode->i_gid = isonum_733(rr->u.PX.gid);
235 break;
236 case SIG('P', 'N'):
237 {
238 int high, low;
239 high = isonum_733(rr->u.PN.dev_high);
240 low = isonum_733(rr->u.PN.dev_low);
241 /*
242 * The Rock Ridge standard specifies that if
243 * sizeof(dev_t) <= 4, then the high field is
244 * unused, and the device number is completely
245 * stored in the low field. Some writers may
246 * ignore this subtlety,
247 * and as a result we test to see if the entire
248 * device number is
249 * stored in the low field, and use that.
250 */
251 if ((low & ~0xff) && high == 0) {
252 inode->i_rdev =
253 MKDEV(low >> 8, low & 0xff);
254 } else {
255 inode->i_rdev =
256 MKDEV(high, low);
232 } 257 }
233 printk("\n"); 258 }
234 break; 259 break;
235 case SIG('P', 'X'): 260 case SIG('T', 'F'):
236 inode->i_mode = isonum_733(rr->u.PX.mode); 261 /*
237 inode->i_nlink = isonum_733(rr->u.PX.n_links); 262 * Some RRIP writers incorrectly place ctime in the
238 inode->i_uid = isonum_733(rr->u.PX.uid); 263 * TF_CREATE field. Try to handle this correctly for
239 inode->i_gid = isonum_733(rr->u.PX.gid); 264 * either case.
240 break; 265 */
241 case SIG('P', 'N'): 266 /* Rock ridge never appears on a High Sierra disk */
242 { 267 cnt = 0;
243 int high, low; 268 if (rr->u.TF.flags & TF_CREATE) {
244 high = isonum_733(rr->u.PN.dev_high); 269 inode->i_ctime.tv_sec =
245 low = isonum_733(rr->u.PN.dev_low); 270 iso_date(rr->u.TF.times[cnt++].time,
246 /* 271 0);
247 * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, 272 inode->i_ctime.tv_nsec = 0;
248 * then the high field is unused, and the device number is completely 273 }
249 * stored in the low field. Some writers may ignore this subtlety, 274 if (rr->u.TF.flags & TF_MODIFY) {
250 * and as a result we test to see if the entire device number is 275 inode->i_mtime.tv_sec =
251 * stored in the low field, and use that. 276 iso_date(rr->u.TF.times[cnt++].time,
252 */ 277 0);
253 if ((low & ~0xff) && high == 0) { 278 inode->i_mtime.tv_nsec = 0;
254 inode->i_rdev = 279 }
255 MKDEV(low >> 8, low & 0xff); 280 if (rr->u.TF.flags & TF_ACCESS) {
256 } else { 281 inode->i_atime.tv_sec =
257 inode->i_rdev = 282 iso_date(rr->u.TF.times[cnt++].time,
258 MKDEV(high, low); 283 0);
284 inode->i_atime.tv_nsec = 0;
285 }
286 if (rr->u.TF.flags & TF_ATTRIBUTES) {
287 inode->i_ctime.tv_sec =
288 iso_date(rr->u.TF.times[cnt++].time,
289 0);
290 inode->i_ctime.tv_nsec = 0;
291 }
292 break;
293 case SIG('S', 'L'):
294 {
295 int slen;
296 struct SL_component *slp;
297 struct SL_component *oldslp;
298 slen = rr->len - 5;
299 slp = &rr->u.SL.link;
300 inode->i_size = symlink_len;
301 while (slen > 1) {
302 rootflag = 0;
303 switch (slp->flags & ~1) {
304 case 0:
305 inode->i_size +=
306 slp->len;
307 break;
308 case 2:
309 inode->i_size += 1;
310 break;
311 case 4:
312 inode->i_size += 2;
313 break;
314 case 8:
315 rootflag = 1;
316 inode->i_size += 1;
317 break;
318 default:
319 printk("Symlink component flag "
320 "not implemented\n");
259 } 321 }
260 } 322 slen -= slp->len + 2;
261 break; 323 oldslp = slp;
262 case SIG('T', 'F'): 324 slp = (struct SL_component *)
263 /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. 325 (((char *)slp) + slp->len + 2);
264 Try to handle this correctly for either case. */ 326
265 cnt = 0; /* Rock ridge never appears on a High Sierra disk */ 327 if (slen < 2) {
266 if (rr->u.TF.flags & TF_CREATE) { 328 if (((rr->u.SL.
267 inode->i_ctime.tv_sec = 329 flags & 1) != 0)
268 iso_date(rr->u.TF.times[cnt++].time, 330 &&
269 0); 331 ((oldslp->
270 inode->i_ctime.tv_nsec = 0; 332 flags & 1) == 0))
271 }
272 if (rr->u.TF.flags & TF_MODIFY) {
273 inode->i_mtime.tv_sec =
274 iso_date(rr->u.TF.times[cnt++].time,
275 0);
276 inode->i_mtime.tv_nsec = 0;
277 }
278 if (rr->u.TF.flags & TF_ACCESS) {
279 inode->i_atime.tv_sec =
280 iso_date(rr->u.TF.times[cnt++].time,
281 0);
282 inode->i_atime.tv_nsec = 0;
283 }
284 if (rr->u.TF.flags & TF_ATTRIBUTES) {
285 inode->i_ctime.tv_sec =
286 iso_date(rr->u.TF.times[cnt++].time,
287 0);
288 inode->i_ctime.tv_nsec = 0;
289 }
290 break;
291 case SIG('S', 'L'):
292 {
293 int slen;
294 struct SL_component *slp;
295 struct SL_component *oldslp;
296 slen = rr->len - 5;
297 slp = &rr->u.SL.link;
298 inode->i_size = symlink_len;
299 while (slen > 1) {
300 rootflag = 0;
301 switch (slp->flags & ~1) {
302 case 0:
303 inode->i_size += 333 inode->i_size +=
304 slp->len; 334 1;
305 break; 335 break;
306 case 2:
307 inode->i_size += 1;
308 break;
309 case 4:
310 inode->i_size += 2;
311 break;
312 case 8:
313 rootflag = 1;
314 inode->i_size += 1;
315 break;
316 default:
317 printk
318 ("Symlink component flag not implemented\n");
319 }
320 slen -= slp->len + 2;
321 oldslp = slp;
322 slp =
323 (struct SL_component
324 *)(((char *)slp) +
325 slp->len + 2);
326
327 if (slen < 2) {
328 if (((rr->u.SL.
329 flags & 1) != 0)
330 &&
331 ((oldslp->
332 flags & 1) == 0))
333 inode->i_size +=
334 1;
335 break;
336 }
337
338 /*
339 * If this component record isn't continued, then append a '/'.
340 */
341 if (!rootflag
342 && (oldslp->flags & 1) == 0)
343 inode->i_size += 1;
344 } 336 }
337
338 /*
339 * If this component record isn't
340 * continued, then append a '/'.
341 */
342 if (!rootflag
343 && (oldslp->flags & 1) == 0)
344 inode->i_size += 1;
345 } 345 }
346 symlink_len = inode->i_size; 346 }
347 break; 347 symlink_len = inode->i_size;
348 case SIG('R', 'E'): 348 break;
349 printk(KERN_WARNING 349 case SIG('R', 'E'):
350 "Attempt to read inode for relocated directory\n"); 350 printk(KERN_WARNING "Attempt to read inode for "
351 "relocated directory\n");
352 goto out;
353 case SIG('C', 'L'):
354 ISOFS_I(inode)->i_first_extent =
355 isonum_733(rr->u.CL.location);
356 reloc =
357 isofs_iget(inode->i_sb,
358 ISOFS_I(inode)->i_first_extent,
359 0);
360 if (!reloc)
351 goto out; 361 goto out;
352 case SIG('C', 'L'): 362 inode->i_mode = reloc->i_mode;
353 ISOFS_I(inode)->i_first_extent = 363 inode->i_nlink = reloc->i_nlink;
354 isonum_733(rr->u.CL.location); 364 inode->i_uid = reloc->i_uid;
355 reloc = 365 inode->i_gid = reloc->i_gid;
356 isofs_iget(inode->i_sb, 366 inode->i_rdev = reloc->i_rdev;
357 ISOFS_I(inode)->i_first_extent, 367 inode->i_size = reloc->i_size;
358 0); 368 inode->i_blocks = reloc->i_blocks;
359 if (!reloc) 369 inode->i_atime = reloc->i_atime;
360 goto out; 370 inode->i_ctime = reloc->i_ctime;
361 inode->i_mode = reloc->i_mode; 371 inode->i_mtime = reloc->i_mtime;
362 inode->i_nlink = reloc->i_nlink; 372 iput(reloc);
363 inode->i_uid = reloc->i_uid; 373 break;
364 inode->i_gid = reloc->i_gid;
365 inode->i_rdev = reloc->i_rdev;
366 inode->i_size = reloc->i_size;
367 inode->i_blocks = reloc->i_blocks;
368 inode->i_atime = reloc->i_atime;
369 inode->i_ctime = reloc->i_ctime;
370 inode->i_mtime = reloc->i_mtime;
371 iput(reloc);
372 break;
373#ifdef CONFIG_ZISOFS 374#ifdef CONFIG_ZISOFS
374 case SIG('Z', 'F'): 375 case SIG('Z', 'F'): {
375 if (!ISOFS_SB(inode->i_sb)->s_nocompress) { 376 int algo;
376 int algo; 377
377 algo = isonum_721(rr->u.ZF.algorithm); 378 if (ISOFS_SB(inode->i_sb)->s_nocompress)
378 if (algo == SIG('p', 'z')) {
379 int block_shift =
380 isonum_711(&rr->u.ZF.
381 parms[1]);
382 if (block_shift <
383 PAGE_CACHE_SHIFT
384 || block_shift > 17) {
385 printk(KERN_WARNING
386 "isofs: Can't handle ZF block size of 2^%d\n",
387 block_shift);
388 } else {
389 /* Note: we don't change i_blocks here */
390 ISOFS_I(inode)->
391 i_file_format =
392 isofs_file_compressed;
393 /* Parameters to compression algorithm (header size, block size) */
394 ISOFS_I(inode)->
395 i_format_parm[0] =
396 isonum_711(&rr->u.
397 ZF.
398 parms
399 [0]);
400 ISOFS_I(inode)->
401 i_format_parm[1] =
402 isonum_711(&rr->u.
403 ZF.
404 parms
405 [1]);
406 inode->i_size =
407 isonum_733(rr->u.ZF.
408 real_size);
409 }
410 } else {
411 printk(KERN_WARNING
412 "isofs: Unknown ZF compression algorithm: %c%c\n",
413 rr->u.ZF.algorithm[0],
414 rr->u.ZF.algorithm[1]);
415 }
416 }
417 break;
418#endif
419 default:
420 break; 379 break;
380 algo = isonum_721(rr->u.ZF.algorithm);
381 if (algo == SIG('p', 'z')) {
382 int block_shift =
383 isonum_711(&rr->u.ZF.parms[1]);
384 if (block_shift < PAGE_CACHE_SHIFT
385 || block_shift > 17) {
386 printk(KERN_WARNING "isofs: "
387 "Can't handle ZF block "
388 "size of 2^%d\n",
389 block_shift);
390 } else {
391 /*
392 * Note: we don't change
393 * i_blocks here
394 */
395 ISOFS_I(inode)->i_file_format =
396 isofs_file_compressed;
397 /*
398 * Parameters to compression
399 * algorithm (header size,
400 * block size)
401 */
402 ISOFS_I(inode)->i_format_parm[0] =
403 isonum_711(&rr->u.ZF.parms[0]);
404 ISOFS_I(inode)->i_format_parm[1] =
405 isonum_711(&rr->u.ZF.parms[1]);
406 inode->i_size =
407 isonum_733(rr->u.ZF.
408 real_size);
409 }
410 } else {
411 printk(KERN_WARNING
412 "isofs: Unknown ZF compression "
413 "algorithm: %c%c\n",
414 rr->u.ZF.algorithm[0],
415 rr->u.ZF.algorithm[1]);
421 } 416 }
417 break;
418 }
419#endif
420 default:
421 break;
422 } 422 }
423 } 423 }
424 MAYBE_CONTINUE(repeat, inode); 424 MAYBE_CONTINUE(repeat, inode);
425 out: 425out:
426 if (buffer) 426 if (buffer)
427 kfree(buffer); 427 kfree(buffer);
428 return 0; 428 return 0;
@@ -553,8 +553,8 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
553 553
554 SETUP_ROCK_RIDGE(raw_inode, chr, len); 554 SETUP_ROCK_RIDGE(raw_inode, chr, len);
555 555
556 repeat: 556repeat:
557 while (len > 2) { /* There may be one byte for padding somewhere */ 557 while (len > 2) { /* There may be one byte for padding somewhere */
558 rr = (struct rock_ridge *)chr; 558 rr = (struct rock_ridge *)chr;
559 if (rr->len < 3) 559 if (rr->len < 3)
560 goto out; /* Something got screwed up here */ 560 goto out; /* Something got screwed up here */
@@ -586,8 +586,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
586 } 586 }
587 } 587 }
588 MAYBE_CONTINUE(repeat, inode); 588 MAYBE_CONTINUE(repeat, inode);
589 if (buffer) 589 kfree(buffer);
590 kfree(buffer);
591 590
592 if (rpnt == link) 591 if (rpnt == link)
593 goto fail; 592 goto fail;
@@ -600,19 +599,19 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
600 return 0; 599 return 0;
601 600
602 /* error exit from macro */ 601 /* error exit from macro */
603 out: 602out:
604 if (buffer) 603 if (buffer)
605 kfree(buffer); 604 kfree(buffer);
606 goto fail; 605 goto fail;
607 out_noread: 606out_noread:
608 printk("unable to read i-node block"); 607 printk("unable to read i-node block");
609 goto fail; 608 goto fail;
610 out_bad_span: 609out_bad_span:
611 printk("symlink spans iso9660 blocks\n"); 610 printk("symlink spans iso9660 blocks\n");
612 fail: 611fail:
613 brelse(bh); 612 brelse(bh);
614 unlock_kernel(); 613 unlock_kernel();
615 error: 614error:
616 SetPageError(page); 615 SetPageError(page);
617 kunmap(page); 616 kunmap(page);
618 unlock_page(page); 617 unlock_page(page);