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.c39
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
291static int 294static int
292parse_rock_ridge_inode_internal(struct iso_directory_record *de, 295parse_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
640int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) 654int 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}