diff options
Diffstat (limited to 'fs/udf/misc.c')
-rw-r--r-- | fs/udf/misc.c | 87 |
1 files changed, 36 insertions, 51 deletions
diff --git a/fs/udf/misc.c b/fs/udf/misc.c index a7f57277a96e..15297deb5051 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c | |||
@@ -54,15 +54,15 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, | |||
54 | int i; | 54 | int i; |
55 | 55 | ||
56 | ea = UDF_I_DATA(inode); | 56 | ea = UDF_I_DATA(inode); |
57 | if (UDF_I_LENEATTR(inode)) | 57 | if (UDF_I_LENEATTR(inode)) { |
58 | ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); | 58 | ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); |
59 | else { | 59 | } else { |
60 | ad = ea; | 60 | ad = ea; |
61 | size += sizeof(struct extendedAttrHeaderDesc); | 61 | size += sizeof(struct extendedAttrHeaderDesc); |
62 | } | 62 | } |
63 | 63 | ||
64 | offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) - | 64 | offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) - |
65 | UDF_I_LENALLOC(inode); | 65 | UDF_I_LENALLOC(inode); |
66 | 66 | ||
67 | /* TODO - Check for FreeEASpace */ | 67 | /* TODO - Check for FreeEASpace */ |
68 | 68 | ||
@@ -76,56 +76,45 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, | |||
76 | 76 | ||
77 | if (UDF_I_LENEATTR(inode)) { | 77 | if (UDF_I_LENEATTR(inode)) { |
78 | /* check checksum/crc */ | 78 | /* check checksum/crc */ |
79 | if (le16_to_cpu(eahd->descTag.tagIdent) != | 79 | if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || |
80 | TAG_IDENT_EAHD | 80 | le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) { |
81 | || le32_to_cpu(eahd->descTag.tagLocation) != | ||
82 | UDF_I_LOCATION(inode).logicalBlockNum) { | ||
83 | return NULL; | 81 | return NULL; |
84 | } | 82 | } |
85 | } else { | 83 | } else { |
86 | size -= sizeof(struct extendedAttrHeaderDesc); | 84 | size -= sizeof(struct extendedAttrHeaderDesc); |
87 | UDF_I_LENEATTR(inode) += | 85 | UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc); |
88 | sizeof(struct extendedAttrHeaderDesc); | ||
89 | eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD); | 86 | eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD); |
90 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) | 87 | if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) |
91 | eahd->descTag.descVersion = cpu_to_le16(3); | 88 | eahd->descTag.descVersion = cpu_to_le16(3); |
92 | else | 89 | else |
93 | eahd->descTag.descVersion = cpu_to_le16(2); | 90 | eahd->descTag.descVersion = cpu_to_le16(2); |
94 | eahd->descTag.tagSerialNum = | 91 | eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); |
95 | cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); | 92 | eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); |
96 | eahd->descTag.tagLocation = | ||
97 | cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); | ||
98 | eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF); | 93 | eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF); |
99 | eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF); | 94 | eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF); |
100 | } | 95 | } |
101 | 96 | ||
102 | offset = UDF_I_LENEATTR(inode); | 97 | offset = UDF_I_LENEATTR(inode); |
103 | if (type < 2048) { | 98 | if (type < 2048) { |
104 | if (le32_to_cpu(eahd->appAttrLocation) < | 99 | if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) { |
105 | UDF_I_LENEATTR(inode)) { | 100 | uint32_t aal = le32_to_cpu(eahd->appAttrLocation); |
106 | uint32_t aal = | 101 | memmove(&ea[offset - aal + size], |
107 | le32_to_cpu(eahd->appAttrLocation); | 102 | &ea[aal], offset - aal); |
108 | memmove(&ea[offset - aal + size], &ea[aal], | ||
109 | offset - aal); | ||
110 | offset -= aal; | 103 | offset -= aal; |
111 | eahd->appAttrLocation = cpu_to_le32(aal + size); | 104 | eahd->appAttrLocation = cpu_to_le32(aal + size); |
112 | } | 105 | } |
113 | if (le32_to_cpu(eahd->impAttrLocation) < | 106 | if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode)) { |
114 | UDF_I_LENEATTR(inode)) { | 107 | uint32_t ial = le32_to_cpu(eahd->impAttrLocation); |
115 | uint32_t ial = | 108 | memmove(&ea[offset - ial + size], |
116 | le32_to_cpu(eahd->impAttrLocation); | 109 | &ea[ial], offset - ial); |
117 | memmove(&ea[offset - ial + size], &ea[ial], | ||
118 | offset - ial); | ||
119 | offset -= ial; | 110 | offset -= ial; |
120 | eahd->impAttrLocation = cpu_to_le32(ial + size); | 111 | eahd->impAttrLocation = cpu_to_le32(ial + size); |
121 | } | 112 | } |
122 | } else if (type < 65536) { | 113 | } else if (type < 65536) { |
123 | if (le32_to_cpu(eahd->appAttrLocation) < | 114 | if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) { |
124 | UDF_I_LENEATTR(inode)) { | 115 | uint32_t aal = le32_to_cpu(eahd->appAttrLocation); |
125 | uint32_t aal = | 116 | memmove(&ea[offset - aal + size], |
126 | le32_to_cpu(eahd->appAttrLocation); | 117 | &ea[aal], offset - aal); |
127 | memmove(&ea[offset - aal + size], &ea[aal], | ||
128 | offset - aal); | ||
129 | offset -= aal; | 118 | offset -= aal; |
130 | eahd->appAttrLocation = cpu_to_le32(aal + size); | 119 | eahd->appAttrLocation = cpu_to_le32(aal + size); |
131 | } | 120 | } |
@@ -133,18 +122,18 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, | |||
133 | /* rewrite CRC + checksum of eahd */ | 122 | /* rewrite CRC + checksum of eahd */ |
134 | crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); | 123 | crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); |
135 | eahd->descTag.descCRCLength = cpu_to_le16(crclen); | 124 | eahd->descTag.descCRCLength = cpu_to_le16(crclen); |
136 | eahd->descTag.descCRC = | 125 | eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + |
137 | cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0)); | 126 | sizeof(tag), crclen, 0)); |
138 | eahd->descTag.tagChecksum = 0; | 127 | eahd->descTag.tagChecksum = 0; |
139 | for (i = 0; i < 16; i++) | 128 | for (i = 0; i < 16; i++) |
140 | if (i != 4) | 129 | if (i != 4) |
141 | eahd->descTag.tagChecksum += | 130 | eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i]; |
142 | ((uint8_t *) & (eahd->descTag))[i]; | ||
143 | UDF_I_LENEATTR(inode) += size; | 131 | UDF_I_LENEATTR(inode) += size; |
144 | return (struct genericFormat *)&ea[offset]; | 132 | return (struct genericFormat *)&ea[offset]; |
145 | } | 133 | } |
146 | if (loc & 0x02) { | 134 | if (loc & 0x02) { |
147 | } | 135 | } |
136 | |||
148 | return NULL; | 137 | return NULL; |
149 | } | 138 | } |
150 | 139 | ||
@@ -163,8 +152,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type, | |||
163 | 152 | ||
164 | /* check checksum/crc */ | 153 | /* check checksum/crc */ |
165 | if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || | 154 | if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || |
166 | le32_to_cpu(eahd->descTag.tagLocation) != | 155 | le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) { |
167 | UDF_I_LOCATION(inode).logicalBlockNum) { | ||
168 | return NULL; | 156 | return NULL; |
169 | } | 157 | } |
170 | 158 | ||
@@ -177,13 +165,13 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type, | |||
177 | 165 | ||
178 | while (offset < UDF_I_LENEATTR(inode)) { | 166 | while (offset < UDF_I_LENEATTR(inode)) { |
179 | gaf = (struct genericFormat *)&ea[offset]; | 167 | gaf = (struct genericFormat *)&ea[offset]; |
180 | if (le32_to_cpu(gaf->attrType) == type | 168 | if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype) |
181 | && gaf->attrSubtype == subtype) | ||
182 | return gaf; | 169 | return gaf; |
183 | else | 170 | else |
184 | offset += le32_to_cpu(gaf->attrLength); | 171 | offset += le32_to_cpu(gaf->attrLength); |
185 | } | 172 | } |
186 | } | 173 | } |
174 | |||
187 | return NULL; | 175 | return NULL; |
188 | } | 176 | } |
189 | 177 | ||
@@ -216,23 +204,22 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, | |||
216 | return NULL; | 204 | return NULL; |
217 | } | 205 | } |
218 | 206 | ||
219 | tag_p = (tag *) (bh->b_data); | 207 | tag_p = (tag *)(bh->b_data); |
220 | 208 | ||
221 | *ident = le16_to_cpu(tag_p->tagIdent); | 209 | *ident = le16_to_cpu(tag_p->tagIdent); |
222 | 210 | ||
223 | if (location != le32_to_cpu(tag_p->tagLocation)) { | 211 | if (location != le32_to_cpu(tag_p->tagLocation)) { |
224 | udf_debug("location mismatch block %u, tag %u != %u\n", | 212 | udf_debug("location mismatch block %u, tag %u != %u\n", |
225 | block + UDF_SB_SESSION(sb), | 213 | block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location); |
226 | le32_to_cpu(tag_p->tagLocation), location); | ||
227 | goto error_out; | 214 | goto error_out; |
228 | } | 215 | } |
229 | 216 | ||
230 | /* Verify the tag checksum */ | 217 | /* Verify the tag checksum */ |
231 | checksum = 0U; | 218 | checksum = 0U; |
232 | for (i = 0; i < 4; i++) | 219 | for (i = 0; i < 4; i++) |
233 | checksum += (uint8_t) (bh->b_data[i]); | 220 | checksum += (uint8_t)(bh->b_data[i]); |
234 | for (i = 5; i < 16; i++) | 221 | for (i = 5; i < 16; i++) |
235 | checksum += (uint8_t) (bh->b_data[i]); | 222 | checksum += (uint8_t)(bh->b_data[i]); |
236 | if (checksum != tag_p->tagChecksum) { | 223 | if (checksum != tag_p->tagChecksum) { |
237 | printk(KERN_ERR "udf: tag checksum failed block %d\n", block); | 224 | printk(KERN_ERR "udf: tag checksum failed block %d\n", block); |
238 | goto error_out; | 225 | goto error_out; |
@@ -249,16 +236,14 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block, | |||
249 | /* Verify the descriptor CRC */ | 236 | /* Verify the descriptor CRC */ |
250 | if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || | 237 | if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || |
251 | le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), | 238 | le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), |
252 | le16_to_cpu(tag_p-> | 239 | le16_to_cpu(tag_p->descCRCLength), 0)) { |
253 | descCRCLength), | ||
254 | 0)) { | ||
255 | return bh; | 240 | return bh; |
256 | } | 241 | } |
257 | udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", | 242 | udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", |
258 | block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), | 243 | block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), |
259 | le16_to_cpu(tag_p->descCRCLength)); | 244 | le16_to_cpu(tag_p->descCRCLength)); |
260 | 245 | ||
261 | error_out: | 246 | error_out: |
262 | brelse(bh); | 247 | brelse(bh); |
263 | return NULL; | 248 | return NULL; |
264 | } | 249 | } |
@@ -272,7 +257,7 @@ struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, | |||
272 | 257 | ||
273 | void udf_update_tag(char *data, int length) | 258 | void udf_update_tag(char *data, int length) |
274 | { | 259 | { |
275 | tag *tptr = (tag *) data; | 260 | tag *tptr = (tag *)data; |
276 | int i; | 261 | int i; |
277 | 262 | ||
278 | length -= sizeof(tag); | 263 | length -= sizeof(tag); |
@@ -283,13 +268,13 @@ void udf_update_tag(char *data, int length) | |||
283 | 268 | ||
284 | for (i = 0; i < 16; i++) | 269 | for (i = 0; i < 16; i++) |
285 | if (i != 4) | 270 | if (i != 4) |
286 | tptr->tagChecksum += (uint8_t) (data[i]); | 271 | tptr->tagChecksum += (uint8_t)(data[i]); |
287 | } | 272 | } |
288 | 273 | ||
289 | void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, | 274 | void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, |
290 | uint32_t loc, int length) | 275 | uint32_t loc, int length) |
291 | { | 276 | { |
292 | tag *tptr = (tag *) data; | 277 | tag *tptr = (tag *)data; |
293 | tptr->tagIdent = cpu_to_le16(ident); | 278 | tptr->tagIdent = cpu_to_le16(ident); |
294 | tptr->descVersion = cpu_to_le16(version); | 279 | tptr->descVersion = cpu_to_le16(version); |
295 | tptr->tagSerialNum = cpu_to_le16(snum); | 280 | tptr->tagSerialNum = cpu_to_le16(snum); |