aboutsummaryrefslogtreecommitdiffstats
path: root/fs/isofs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r--fs/isofs/inode.c75
1 files changed, 53 insertions, 22 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 5a44811b5027..bfdeb82a53be 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -17,7 +17,6 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/nls.h> 18#include <linux/nls.h>
19#include <linux/ctype.h> 19#include <linux/ctype.h>
20#include <linux/smp_lock.h>
21#include <linux/statfs.h> 20#include <linux/statfs.h>
22#include <linux/cdrom.h> 21#include <linux/cdrom.h>
23#include <linux/parser.h> 22#include <linux/parser.h>
@@ -44,11 +43,7 @@ static void isofs_put_super(struct super_block *sb)
44 struct isofs_sb_info *sbi = ISOFS_SB(sb); 43 struct isofs_sb_info *sbi = ISOFS_SB(sb);
45 44
46#ifdef CONFIG_JOLIET 45#ifdef CONFIG_JOLIET
47 lock_kernel();
48
49 unload_nls(sbi->s_nls_iocharset); 46 unload_nls(sbi->s_nls_iocharset);
50
51 unlock_kernel();
52#endif 47#endif
53 48
54 kfree(sbi); 49 kfree(sbi);
@@ -549,6 +544,34 @@ static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
549} 544}
550 545
551/* 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/*
552 * Initialize the superblock and read the root inode. 575 * Initialize the superblock and read the root inode.
553 * 576 *
554 * Note: a check_disk_change() has been done immediately prior 577 * Note: a check_disk_change() has been done immediately prior
@@ -823,6 +846,7 @@ root_found:
823 sbi->s_utf8 = opt.utf8; 846 sbi->s_utf8 = opt.utf8;
824 sbi->s_nocompress = opt.nocompress; 847 sbi->s_nocompress = opt.nocompress;
825 sbi->s_overriderockperm = opt.overriderockperm; 848 sbi->s_overriderockperm = opt.overriderockperm;
849 mutex_init(&sbi->s_mutex);
826 /* 850 /*
827 * It would be incredibly stupid to allow people to mark every file 851 * It would be incredibly stupid to allow people to mark every file
828 * on the disk as suid, so we merely allow them to set the default 852 * on the disk as suid, so we merely allow them to set the default
@@ -847,6 +871,18 @@ root_found:
847 goto out_no_root; 871 goto out_no_root;
848 872
849 /* 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 /*
850 * 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
851 * want to use Rock Ridge by default. This can be overridden 887 * want to use Rock Ridge by default. This can be overridden
852 * by using the norock mount option. There is still one other 888 * by using the norock mount option. There is still one other
@@ -966,27 +1002,23 @@ static int isofs_statfs (struct dentry *dentry, struct kstatfs *buf)
966 * or getblk() if they are not. Returns the number of blocks inserted 1002 * or getblk() if they are not. Returns the number of blocks inserted
967 * (-ve == error.) 1003 * (-ve == error.)
968 */ 1004 */
969int isofs_get_blocks(struct inode *inode, sector_t iblock_s, 1005int isofs_get_blocks(struct inode *inode, sector_t iblock,
970 struct buffer_head **bh, unsigned long nblocks) 1006 struct buffer_head **bh, unsigned long nblocks)
971{ 1007{
972 unsigned long b_off; 1008 unsigned long b_off = iblock;
973 unsigned offset, sect_size; 1009 unsigned offset, sect_size;
974 unsigned int firstext; 1010 unsigned int firstext;
975 unsigned long nextblk, nextoff; 1011 unsigned long nextblk, nextoff;
976 long iblock = (long)iblock_s;
977 int section, rv, error; 1012 int section, rv, error;
978 struct iso_inode_info *ei = ISOFS_I(inode); 1013 struct iso_inode_info *ei = ISOFS_I(inode);
979 1014
980 lock_kernel();
981
982 error = -EIO; 1015 error = -EIO;
983 rv = 0; 1016 rv = 0;
984 if (iblock < 0 || iblock != iblock_s) { 1017 if (iblock != b_off) {
985 printk(KERN_DEBUG "%s: block number too large\n", __func__); 1018 printk(KERN_DEBUG "%s: block number too large\n", __func__);
986 goto abort; 1019 goto abort;
987 } 1020 }
988 1021
989 b_off = iblock;
990 1022
991 offset = 0; 1023 offset = 0;
992 firstext = ei->i_first_extent; 1024 firstext = ei->i_first_extent;
@@ -1004,8 +1036,9 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1004 * I/O errors. 1036 * I/O errors.
1005 */ 1037 */
1006 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) { 1038 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) {
1007 printk(KERN_DEBUG "%s: block >= EOF (%ld, %ld)\n", 1039 printk(KERN_DEBUG "%s: block >= EOF (%lu, %llu)\n",
1008 __func__, iblock, (unsigned long) inode->i_size); 1040 __func__, b_off,
1041 (unsigned long long)inode->i_size);
1009 goto abort; 1042 goto abort;
1010 } 1043 }
1011 1044
@@ -1031,9 +1064,9 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1031 if (++section > 100) { 1064 if (++section > 100) {
1032 printk(KERN_DEBUG "%s: More than 100 file sections ?!?" 1065 printk(KERN_DEBUG "%s: More than 100 file sections ?!?"
1033 " aborting...\n", __func__); 1066 " aborting...\n", __func__);
1034 printk(KERN_DEBUG "%s: block=%ld firstext=%u sect_size=%u " 1067 printk(KERN_DEBUG "%s: block=%lu firstext=%u sect_size=%u "
1035 "nextblk=%lu nextoff=%lu\n", __func__, 1068 "nextblk=%lu nextoff=%lu\n", __func__,
1036 iblock, firstext, (unsigned) sect_size, 1069 b_off, firstext, (unsigned) sect_size,
1037 nextblk, nextoff); 1070 nextblk, nextoff);
1038 goto abort; 1071 goto abort;
1039 } 1072 }
@@ -1054,7 +1087,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1054 1087
1055 error = 0; 1088 error = 0;
1056abort: 1089abort:
1057 unlock_kernel();
1058 return rv != 0 ? rv : error; 1090 return rv != 0 ? rv : error;
1059} 1091}
1060 1092
@@ -1475,17 +1507,16 @@ struct inode *isofs_iget(struct super_block *sb,
1475 return inode; 1507 return inode;
1476} 1508}
1477 1509
1478static int isofs_get_sb(struct file_system_type *fs_type, 1510static struct dentry *isofs_mount(struct file_system_type *fs_type,
1479 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 1511 int flags, const char *dev_name, void *data)
1480{ 1512{
1481 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super, 1513 return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
1482 mnt);
1483} 1514}
1484 1515
1485static struct file_system_type iso9660_fs_type = { 1516static struct file_system_type iso9660_fs_type = {
1486 .owner = THIS_MODULE, 1517 .owner = THIS_MODULE,
1487 .name = "iso9660", 1518 .name = "iso9660",
1488 .get_sb = isofs_get_sb, 1519 .mount = isofs_mount,
1489 .kill_sb = kill_block_super, 1520 .kill_sb = kill_block_super,
1490 .fs_flags = FS_REQUIRES_DEV, 1521 .fs_flags = FS_REQUIRES_DEV,
1491}; 1522};