diff options
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 839a2bad7f45..91219385691d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -94,13 +94,25 @@ static unsigned int udf_count_free(struct super_block *); | |||
94 | static int udf_statfs(struct dentry *, struct kstatfs *); | 94 | static int udf_statfs(struct dentry *, struct kstatfs *); |
95 | static int udf_show_options(struct seq_file *, struct dentry *); | 95 | static int udf_show_options(struct seq_file *, struct dentry *); |
96 | 96 | ||
97 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) | 97 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb) |
98 | { | 98 | { |
99 | struct logicalVolIntegrityDesc *lvid = | 99 | struct logicalVolIntegrityDesc *lvid; |
100 | (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; | 100 | unsigned int partnum; |
101 | __u32 number_of_partitions = le32_to_cpu(lvid->numOfPartitions); | 101 | unsigned int offset; |
102 | __u32 offset = number_of_partitions * 2 * | 102 | |
103 | sizeof(uint32_t)/sizeof(uint8_t); | 103 | if (!UDF_SB(sb)->s_lvid_bh) |
104 | return NULL; | ||
105 | lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data; | ||
106 | partnum = le32_to_cpu(lvid->numOfPartitions); | ||
107 | if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) - | ||
108 | offsetof(struct logicalVolIntegrityDesc, impUse)) / | ||
109 | (2 * sizeof(uint32_t)) < partnum) { | ||
110 | udf_err(sb, "Logical volume integrity descriptor corrupted " | ||
111 | "(numOfPartitions = %u)!\n", partnum); | ||
112 | return NULL; | ||
113 | } | ||
114 | /* The offset is to skip freeSpaceTable and sizeTable arrays */ | ||
115 | offset = partnum * 2 * sizeof(uint32_t); | ||
104 | return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); | 116 | return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); |
105 | } | 117 | } |
106 | 118 | ||
@@ -629,9 +641,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
629 | struct udf_options uopt; | 641 | struct udf_options uopt; |
630 | struct udf_sb_info *sbi = UDF_SB(sb); | 642 | struct udf_sb_info *sbi = UDF_SB(sb); |
631 | int error = 0; | 643 | int error = 0; |
644 | struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); | ||
632 | 645 | ||
633 | if (sbi->s_lvid_bh) { | 646 | if (lvidiu) { |
634 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 647 | int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev); |
635 | if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) | 648 | if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) |
636 | return -EACCES; | 649 | return -EACCES; |
637 | } | 650 | } |
@@ -1905,11 +1918,12 @@ static void udf_open_lvid(struct super_block *sb) | |||
1905 | 1918 | ||
1906 | if (!bh) | 1919 | if (!bh) |
1907 | return; | 1920 | return; |
1908 | |||
1909 | mutex_lock(&sbi->s_alloc_mutex); | ||
1910 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1921 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
1911 | lvidiu = udf_sb_lvidiu(sbi); | 1922 | lvidiu = udf_sb_lvidiu(sb); |
1923 | if (!lvidiu) | ||
1924 | return; | ||
1912 | 1925 | ||
1926 | mutex_lock(&sbi->s_alloc_mutex); | ||
1913 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1927 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1914 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1928 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1915 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, | 1929 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, |
@@ -1937,10 +1951,12 @@ static void udf_close_lvid(struct super_block *sb) | |||
1937 | 1951 | ||
1938 | if (!bh) | 1952 | if (!bh) |
1939 | return; | 1953 | return; |
1954 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1955 | lvidiu = udf_sb_lvidiu(sb); | ||
1956 | if (!lvidiu) | ||
1957 | return; | ||
1940 | 1958 | ||
1941 | mutex_lock(&sbi->s_alloc_mutex); | 1959 | mutex_lock(&sbi->s_alloc_mutex); |
1942 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
1943 | lvidiu = udf_sb_lvidiu(sbi); | ||
1944 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1960 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1945 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1961 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1946 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); | 1962 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); |
@@ -2093,15 +2109,19 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2093 | 2109 | ||
2094 | if (sbi->s_lvid_bh) { | 2110 | if (sbi->s_lvid_bh) { |
2095 | struct logicalVolIntegrityDescImpUse *lvidiu = | 2111 | struct logicalVolIntegrityDescImpUse *lvidiu = |
2096 | udf_sb_lvidiu(sbi); | 2112 | udf_sb_lvidiu(sb); |
2097 | uint16_t minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); | 2113 | uint16_t minUDFReadRev; |
2098 | uint16_t minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); | 2114 | uint16_t minUDFWriteRev; |
2099 | /* uint16_t maxUDFWriteRev = | ||
2100 | le16_to_cpu(lvidiu->maxUDFWriteRev); */ | ||
2101 | 2115 | ||
2116 | if (!lvidiu) { | ||
2117 | ret = -EINVAL; | ||
2118 | goto error_out; | ||
2119 | } | ||
2120 | minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); | ||
2121 | minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); | ||
2102 | if (minUDFReadRev > UDF_MAX_READ_VERSION) { | 2122 | if (minUDFReadRev > UDF_MAX_READ_VERSION) { |
2103 | udf_err(sb, "minUDFReadRev=%x (max is %x)\n", | 2123 | udf_err(sb, "minUDFReadRev=%x (max is %x)\n", |
2104 | le16_to_cpu(lvidiu->minUDFReadRev), | 2124 | minUDFReadRev, |
2105 | UDF_MAX_READ_VERSION); | 2125 | UDF_MAX_READ_VERSION); |
2106 | ret = -EINVAL; | 2126 | ret = -EINVAL; |
2107 | goto error_out; | 2127 | goto error_out; |
@@ -2265,11 +2285,7 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
2265 | struct logicalVolIntegrityDescImpUse *lvidiu; | 2285 | struct logicalVolIntegrityDescImpUse *lvidiu; |
2266 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | 2286 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
2267 | 2287 | ||
2268 | if (sbi->s_lvid_bh != NULL) | 2288 | lvidiu = udf_sb_lvidiu(sb); |
2269 | lvidiu = udf_sb_lvidiu(sbi); | ||
2270 | else | ||
2271 | lvidiu = NULL; | ||
2272 | |||
2273 | buf->f_type = UDF_SUPER_MAGIC; | 2289 | buf->f_type = UDF_SUPER_MAGIC; |
2274 | buf->f_bsize = sb->s_blocksize; | 2290 | buf->f_bsize = sb->s_blocksize; |
2275 | buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; | 2291 | buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; |