diff options
Diffstat (limited to 'fs/isofs/rock.c')
-rw-r--r-- | fs/isofs/rock.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index c0bf42472e40..f488bbae541a 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
@@ -288,12 +288,16 @@ eio: | |||
288 | goto out; | 288 | goto out; |
289 | } | 289 | } |
290 | 290 | ||
291 | #define RR_REGARD_XA 1 | ||
292 | #define RR_RELOC_DE 2 | ||
293 | |||
291 | static int | 294 | static int |
292 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, | 295 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, |
293 | struct inode *inode, int regard_xa) | 296 | struct inode *inode, int flags) |
294 | { | 297 | { |
295 | int symlink_len = 0; | 298 | int symlink_len = 0; |
296 | int cnt, sig; | 299 | int cnt, sig; |
300 | unsigned int reloc_block; | ||
297 | struct inode *reloc; | 301 | struct inode *reloc; |
298 | struct rock_ridge *rr; | 302 | struct rock_ridge *rr; |
299 | int rootflag; | 303 | int rootflag; |
@@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, | |||
305 | 309 | ||
306 | init_rock_state(&rs, inode); | 310 | init_rock_state(&rs, inode); |
307 | setup_rock_ridge(de, inode, &rs); | 311 | setup_rock_ridge(de, inode, &rs); |
308 | if (regard_xa) { | 312 | if (flags & RR_REGARD_XA) { |
309 | rs.chr += 14; | 313 | rs.chr += 14; |
310 | rs.len -= 14; | 314 | rs.len -= 14; |
311 | if (rs.len < 0) | 315 | if (rs.len < 0) |
@@ -485,12 +489,22 @@ repeat: | |||
485 | "relocated directory\n"); | 489 | "relocated directory\n"); |
486 | goto out; | 490 | goto out; |
487 | case SIG('C', 'L'): | 491 | case SIG('C', 'L'): |
488 | ISOFS_I(inode)->i_first_extent = | 492 | if (flags & RR_RELOC_DE) { |
489 | isonum_733(rr->u.CL.location); | 493 | printk(KERN_ERR |
490 | reloc = | 494 | "ISOFS: Recursive directory relocation " |
491 | isofs_iget(inode->i_sb, | 495 | "is not supported\n"); |
492 | ISOFS_I(inode)->i_first_extent, | 496 | goto eio; |
493 | 0); | 497 | } |
498 | reloc_block = isonum_733(rr->u.CL.location); | ||
499 | if (reloc_block == ISOFS_I(inode)->i_iget5_block && | ||
500 | ISOFS_I(inode)->i_iget5_offset == 0) { | ||
501 | printk(KERN_ERR | ||
502 | "ISOFS: Directory relocation points to " | ||
503 | "itself\n"); | ||
504 | goto eio; | ||
505 | } | ||
506 | ISOFS_I(inode)->i_first_extent = reloc_block; | ||
507 | reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); | ||
494 | if (IS_ERR(reloc)) { | 508 | if (IS_ERR(reloc)) { |
495 | ret = PTR_ERR(reloc); | 509 | ret = PTR_ERR(reloc); |
496 | goto out; | 510 | goto out; |
@@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) | |||
637 | return rpnt; | 651 | return rpnt; |
638 | } | 652 | } |
639 | 653 | ||
640 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | 654 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, |
655 | int relocated) | ||
641 | { | 656 | { |
642 | int result = parse_rock_ridge_inode_internal(de, inode, 0); | 657 | int flags = relocated ? RR_RELOC_DE : 0; |
658 | int result = parse_rock_ridge_inode_internal(de, inode, flags); | ||
643 | 659 | ||
644 | /* | 660 | /* |
645 | * if rockridge flag was reset and we didn't look for attributes | 661 | * if rockridge flag was reset and we didn't look for attributes |
@@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | |||
647 | */ | 663 | */ |
648 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) | 664 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) |
649 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { | 665 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { |
650 | result = parse_rock_ridge_inode_internal(de, inode, 14); | 666 | result = parse_rock_ridge_inode_internal(de, inode, |
667 | flags | RR_REGARD_XA); | ||
651 | } | 668 | } |
652 | return result; | 669 | return result; |
653 | } | 670 | } |