aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2010-10-27 18:33:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:08 -0400
commite45c9effed903ba3fdbd6ef0498ee8989c35af0a (patch)
treefb754f3858b2188e95e63c435b2844fe5c476661
parentb4754ebc319ca2e8eb95e51a5d2e2d00047c4db9 (diff)
isofs: work-around for Rock Ridge+Joliet CDs with empty ISO root directory
If a CD has both Rock Ridge and Joliet extensions and the ISO root directory is empty, no files are visible. Disable Rock Ridge extensions in this case and use Joliet root directory instead. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Guenter Roeck <guenter.roeck@ericsson.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/isofs/inode.c40
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 */
553static 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