diff options
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r-- | fs/isofs/inode.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 60c2b944d762..79cf7f616bbe 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -544,6 +544,34 @@ static unsigned int isofs_get_last_session(struct super_block *sb, s32 session) | |||
544 | } | 544 | } |
545 | 545 | ||
546 | /* | 546 | /* |
547 | * Check if root directory is empty (has less than 3 files). | ||
548 | * | ||
549 | * Used to detect broken CDs where ISO root directory is empty but Joliet root | ||
550 | * directory is OK. If such CD has Rock Ridge extensions, they will be disabled | ||
551 | * (and Joliet used instead) or else no files would be visible. | ||
552 | */ | ||
553 | static bool rootdir_empty(struct super_block *sb, unsigned long block) | ||
554 | { | ||
555 | int offset = 0, files = 0, de_len; | ||
556 | struct iso_directory_record *de; | ||
557 | struct buffer_head *bh; | ||
558 | |||
559 | bh = sb_bread(sb, block); | ||
560 | if (!bh) | ||
561 | return true; | ||
562 | while (files < 3) { | ||
563 | de = (struct iso_directory_record *) (bh->b_data + offset); | ||
564 | de_len = *(unsigned char *) de; | ||
565 | if (de_len == 0) | ||
566 | break; | ||
567 | files++; | ||
568 | offset += de_len; | ||
569 | } | ||
570 | brelse(bh); | ||
571 | return files < 3; | ||
572 | } | ||
573 | |||
574 | /* | ||
547 | * Initialize the superblock and read the root inode. | 575 | * Initialize the superblock and read the root inode. |
548 | * | 576 | * |
549 | * Note: a check_disk_change() has been done immediately prior | 577 | * Note: a check_disk_change() has been done immediately prior |
@@ -843,6 +871,18 @@ root_found: | |||
843 | goto out_no_root; | 871 | goto out_no_root; |
844 | 872 | ||
845 | /* | 873 | /* |
874 | * Fix for broken CDs with Rock Ridge and empty ISO root directory but | ||
875 | * correct Joliet root directory. | ||
876 | */ | ||
877 | if (sbi->s_rock == 1 && joliet_level && | ||
878 | rootdir_empty(s, sbi->s_firstdatazone)) { | ||
879 | printk(KERN_NOTICE | ||
880 | "ISOFS: primary root directory is empty. " | ||
881 | "Disabling Rock Ridge and switching to Joliet."); | ||
882 | sbi->s_rock = 0; | ||
883 | } | ||
884 | |||
885 | /* | ||
846 | * If this disk has both Rock Ridge and Joliet on it, then we | 886 | * If this disk has both Rock Ridge and Joliet on it, then we |
847 | * want to use Rock Ridge by default. This can be overridden | 887 | * want to use Rock Ridge by default. This can be overridden |
848 | * by using the norock mount option. There is still one other | 888 | * by using the norock mount option. There is still one other |