diff options
| -rw-r--r-- | fs/udf/ialloc.c | 16 | ||||
| -rw-r--r-- | fs/udf/super.c | 64 | ||||
| -rw-r--r-- | fs/udf/udf_sb.h | 2 |
3 files changed, 48 insertions, 34 deletions
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 7e5aae4bf46f..6eaf5edf1ea1 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
| @@ -30,18 +30,17 @@ void udf_free_inode(struct inode *inode) | |||
| 30 | { | 30 | { |
| 31 | struct super_block *sb = inode->i_sb; | 31 | struct super_block *sb = inode->i_sb; |
| 32 | struct udf_sb_info *sbi = UDF_SB(sb); | 32 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 33 | struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); | ||
| 33 | 34 | ||
| 34 | mutex_lock(&sbi->s_alloc_mutex); | 35 | if (lvidiu) { |
| 35 | if (sbi->s_lvid_bh) { | 36 | mutex_lock(&sbi->s_alloc_mutex); |
| 36 | struct logicalVolIntegrityDescImpUse *lvidiu = | ||
| 37 | udf_sb_lvidiu(sbi); | ||
| 38 | if (S_ISDIR(inode->i_mode)) | 37 | if (S_ISDIR(inode->i_mode)) |
| 39 | le32_add_cpu(&lvidiu->numDirs, -1); | 38 | le32_add_cpu(&lvidiu->numDirs, -1); |
| 40 | else | 39 | else |
| 41 | le32_add_cpu(&lvidiu->numFiles, -1); | 40 | le32_add_cpu(&lvidiu->numFiles, -1); |
| 42 | udf_updated_lvid(sb); | 41 | udf_updated_lvid(sb); |
| 42 | mutex_unlock(&sbi->s_alloc_mutex); | ||
| 43 | } | 43 | } |
| 44 | mutex_unlock(&sbi->s_alloc_mutex); | ||
| 45 | 44 | ||
| 46 | udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); | 45 | udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); |
| 47 | } | 46 | } |
| @@ -55,6 +54,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) | |||
| 55 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; | 54 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; |
| 56 | struct udf_inode_info *iinfo; | 55 | struct udf_inode_info *iinfo; |
| 57 | struct udf_inode_info *dinfo = UDF_I(dir); | 56 | struct udf_inode_info *dinfo = UDF_I(dir); |
| 57 | struct logicalVolIntegrityDescImpUse *lvidiu; | ||
| 58 | 58 | ||
| 59 | inode = new_inode(sb); | 59 | inode = new_inode(sb); |
| 60 | 60 | ||
| @@ -92,12 +92,10 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) | |||
| 92 | return NULL; | 92 | return NULL; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | if (sbi->s_lvid_bh) { | 95 | lvidiu = udf_sb_lvidiu(sb); |
| 96 | struct logicalVolIntegrityDescImpUse *lvidiu; | 96 | if (lvidiu) { |
| 97 | |||
| 98 | iinfo->i_unique = lvid_get_unique_id(sb); | 97 | iinfo->i_unique = lvid_get_unique_id(sb); |
| 99 | mutex_lock(&sbi->s_alloc_mutex); | 98 | mutex_lock(&sbi->s_alloc_mutex); |
| 100 | lvidiu = udf_sb_lvidiu(sbi); | ||
| 101 | if (S_ISDIR(mode)) | 99 | if (S_ISDIR(mode)) |
| 102 | le32_add_cpu(&lvidiu->numDirs, 1); | 100 | le32_add_cpu(&lvidiu->numDirs, 1); |
| 103 | else | 101 | else |
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; |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index ed401e94aa8c..1f32c7bd9f57 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
| @@ -162,7 +162,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | |||
| 162 | return sb->s_fs_info; | 162 | return sb->s_fs_info; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); | 165 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb); |
| 166 | 166 | ||
| 167 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); | 167 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); |
| 168 | 168 | ||
