aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/misc.c')
-rw-r--r--fs/udf/misc.c172
1 files changed, 84 insertions, 88 deletions
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index a2b2a98ce78a..a7f57277a96e 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -29,8 +29,7 @@
29#include "udf_i.h" 29#include "udf_i.h"
30#include "udf_sb.h" 30#include "udf_sb.h"
31 31
32struct buffer_head * 32struct buffer_head *udf_tgetblk(struct super_block *sb, int block)
33udf_tgetblk(struct super_block *sb, int block)
34{ 33{
35 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) 34 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
36 return sb_getblk(sb, udf_fixed_to_variable(block)); 35 return sb_getblk(sb, udf_fixed_to_variable(block));
@@ -38,8 +37,7 @@ udf_tgetblk(struct super_block *sb, int block)
38 return sb_getblk(sb, block); 37 return sb_getblk(sb, block);
39} 38}
40 39
41struct buffer_head * 40struct buffer_head *udf_tread(struct super_block *sb, int block)
42udf_tread(struct super_block *sb, int block)
43{ 41{
44 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV)) 42 if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
45 return sb_bread(sb, udf_fixed_to_variable(block)); 43 return sb_bread(sb, udf_fixed_to_variable(block));
@@ -47,9 +45,8 @@ udf_tread(struct super_block *sb, int block)
47 return sb_bread(sb, block); 45 return sb_bread(sb, block);
48} 46}
49 47
50struct genericFormat * 48struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
51udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type, 49 uint32_t type, uint8_t loc)
52 uint8_t loc)
53{ 50{
54 uint8_t *ea = NULL, *ad = NULL; 51 uint8_t *ea = NULL, *ad = NULL;
55 int offset; 52 int offset;
@@ -59,78 +56,76 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
59 ea = UDF_I_DATA(inode); 56 ea = UDF_I_DATA(inode);
60 if (UDF_I_LENEATTR(inode)) 57 if (UDF_I_LENEATTR(inode))
61 ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); 58 ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
62 else 59 else {
63 {
64 ad = ea; 60 ad = ea;
65 size += sizeof(struct extendedAttrHeaderDesc); 61 size += sizeof(struct extendedAttrHeaderDesc);
66 } 62 }
67 63
68 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) -
69 UDF_I_LENALLOC(inode); 65 UDF_I_LENALLOC(inode);
70 66
71 /* TODO - Check for FreeEASpace */ 67 /* TODO - Check for FreeEASpace */
72 68
73 if (loc & 0x01 && offset >= size) 69 if (loc & 0x01 && offset >= size) {
74 {
75 struct extendedAttrHeaderDesc *eahd; 70 struct extendedAttrHeaderDesc *eahd;
76 eahd = (struct extendedAttrHeaderDesc *)ea; 71 eahd = (struct extendedAttrHeaderDesc *)ea;
77 72
78 if (UDF_I_LENALLOC(inode)) 73 if (UDF_I_LENALLOC(inode)) {
79 {
80 memmove(&ad[size], ad, UDF_I_LENALLOC(inode)); 74 memmove(&ad[size], ad, UDF_I_LENALLOC(inode));
81 } 75 }
82 76
83 if (UDF_I_LENEATTR(inode)) 77 if (UDF_I_LENEATTR(inode)) {
84 {
85 /* check checksum/crc */ 78 /* check checksum/crc */
86 if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || 79 if (le16_to_cpu(eahd->descTag.tagIdent) !=
87 le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) 80 TAG_IDENT_EAHD
88 { 81 || le32_to_cpu(eahd->descTag.tagLocation) !=
82 UDF_I_LOCATION(inode).logicalBlockNum) {
89 return NULL; 83 return NULL;
90 } 84 }
91 } 85 } else {
92 else
93 {
94 size -= sizeof(struct extendedAttrHeaderDesc); 86 size -= sizeof(struct extendedAttrHeaderDesc);
95 UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc); 87 UDF_I_LENEATTR(inode) +=
88 sizeof(struct extendedAttrHeaderDesc);
96 eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD); 89 eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD);
97 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200) 90 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
98 eahd->descTag.descVersion = cpu_to_le16(3); 91 eahd->descTag.descVersion = cpu_to_le16(3);
99 else 92 else
100 eahd->descTag.descVersion = cpu_to_le16(2); 93 eahd->descTag.descVersion = cpu_to_le16(2);
101 eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb)); 94 eahd->descTag.tagSerialNum =
102 eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum); 95 cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
96 eahd->descTag.tagLocation =
97 cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
103 eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF); 98 eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
104 eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF); 99 eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
105 } 100 }
106 101
107 offset = UDF_I_LENEATTR(inode); 102 offset = UDF_I_LENEATTR(inode);
108 if (type < 2048) 103 if (type < 2048) {
109 { 104 if (le32_to_cpu(eahd->appAttrLocation) <
110 if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) 105 UDF_I_LENEATTR(inode)) {
111 { 106 uint32_t aal =
112 uint32_t aal = le32_to_cpu(eahd->appAttrLocation); 107 le32_to_cpu(eahd->appAttrLocation);
113 memmove(&ea[offset - aal + size], 108 memmove(&ea[offset - aal + size], &ea[aal],
114 &ea[aal], offset - aal); 109 offset - aal);
115 offset -= aal; 110 offset -= aal;
116 eahd->appAttrLocation = cpu_to_le32(aal + size); 111 eahd->appAttrLocation = cpu_to_le32(aal + size);
117 } 112 }
118 if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode)) 113 if (le32_to_cpu(eahd->impAttrLocation) <
119 { 114 UDF_I_LENEATTR(inode)) {
120 uint32_t ial = le32_to_cpu(eahd->impAttrLocation); 115 uint32_t ial =
121 memmove(&ea[offset - ial + size], 116 le32_to_cpu(eahd->impAttrLocation);
122 &ea[ial], offset - ial); 117 memmove(&ea[offset - ial + size], &ea[ial],
118 offset - ial);
123 offset -= ial; 119 offset -= ial;
124 eahd->impAttrLocation = cpu_to_le32(ial + size); 120 eahd->impAttrLocation = cpu_to_le32(ial + size);
125 } 121 }
126 } 122 } else if (type < 65536) {
127 else if (type < 65536) 123 if (le32_to_cpu(eahd->appAttrLocation) <
128 { 124 UDF_I_LENEATTR(inode)) {
129 if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) 125 uint32_t aal =
130 { 126 le32_to_cpu(eahd->appAttrLocation);
131 uint32_t aal = le32_to_cpu(eahd->appAttrLocation); 127 memmove(&ea[offset - aal + size], &ea[aal],
132 memmove(&ea[offset - aal + size], 128 offset - aal);
133 &ea[aal], offset - aal);
134 offset -= aal; 129 offset -= aal;
135 eahd->appAttrLocation = cpu_to_le32(aal + size); 130 eahd->appAttrLocation = cpu_to_le32(aal + size);
136 } 131 }
@@ -138,22 +133,23 @@ udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
138 /* rewrite CRC + checksum of eahd */ 133 /* rewrite CRC + checksum of eahd */
139 crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); 134 crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
140 eahd->descTag.descCRCLength = cpu_to_le16(crclen); 135 eahd->descTag.descCRCLength = cpu_to_le16(crclen);
141 eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0)); 136 eahd->descTag.descCRC =
137 cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0));
142 eahd->descTag.tagChecksum = 0; 138 eahd->descTag.tagChecksum = 0;
143 for (i=0; i<16; i++) 139 for (i = 0; i < 16; i++)
144 if (i != 4) 140 if (i != 4)
145 eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i]; 141 eahd->descTag.tagChecksum +=
142 ((uint8_t *) & (eahd->descTag))[i];
146 UDF_I_LENEATTR(inode) += size; 143 UDF_I_LENEATTR(inode) += size;
147 return (struct genericFormat *)&ea[offset]; 144 return (struct genericFormat *)&ea[offset];
148 } 145 }
149 if (loc & 0x02) 146 if (loc & 0x02) {
150 {
151 } 147 }
152 return NULL; 148 return NULL;
153} 149}
154 150
155struct genericFormat * 151struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
156udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype) 152 uint8_t subtype)
157{ 153{
158 struct genericFormat *gaf; 154 struct genericFormat *gaf;
159 uint8_t *ea = NULL; 155 uint8_t *ea = NULL;
@@ -161,18 +157,17 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
161 157
162 ea = UDF_I_DATA(inode); 158 ea = UDF_I_DATA(inode);
163 159
164 if (UDF_I_LENEATTR(inode)) 160 if (UDF_I_LENEATTR(inode)) {
165 {
166 struct extendedAttrHeaderDesc *eahd; 161 struct extendedAttrHeaderDesc *eahd;
167 eahd = (struct extendedAttrHeaderDesc *)ea; 162 eahd = (struct extendedAttrHeaderDesc *)ea;
168 163
169 /* check checksum/crc */ 164 /* check checksum/crc */
170 if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD || 165 if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
171 le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) 166 le32_to_cpu(eahd->descTag.tagLocation) !=
172 { 167 UDF_I_LOCATION(inode).logicalBlockNum) {
173 return NULL; 168 return NULL;
174 } 169 }
175 170
176 if (type < 2048) 171 if (type < 2048)
177 offset = sizeof(struct extendedAttrHeaderDesc); 172 offset = sizeof(struct extendedAttrHeaderDesc);
178 else if (type < 65536) 173 else if (type < 65536)
@@ -180,10 +175,10 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
180 else 175 else
181 offset = le32_to_cpu(eahd->appAttrLocation); 176 offset = le32_to_cpu(eahd->appAttrLocation);
182 177
183 while (offset < UDF_I_LENEATTR(inode)) 178 while (offset < UDF_I_LENEATTR(inode)) {
184 {
185 gaf = (struct genericFormat *)&ea[offset]; 179 gaf = (struct genericFormat *)&ea[offset];
186 if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype) 180 if (le32_to_cpu(gaf->attrType) == type
181 && gaf->attrSubtype == subtype)
187 return gaf; 182 return gaf;
188 else 183 else
189 offset += le32_to_cpu(gaf->attrLength); 184 offset += le32_to_cpu(gaf->attrLength);
@@ -202,8 +197,8 @@ udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
202 * July 1, 1997 - Andrew E. Mileski 197 * July 1, 1997 - Andrew E. Mileski
203 * Written, tested, and released. 198 * Written, tested, and released.
204 */ 199 */
205struct buffer_head * 200struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
206udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident) 201 uint32_t location, uint16_t * ident)
207{ 202{
208 tag *tag_p; 203 tag *tag_p;
209 struct buffer_head *bh = NULL; 204 struct buffer_head *bh = NULL;
@@ -215,29 +210,29 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
215 return NULL; 210 return NULL;
216 211
217 bh = udf_tread(sb, block + UDF_SB_SESSION(sb)); 212 bh = udf_tread(sb, block + UDF_SB_SESSION(sb));
218 if (!bh) 213 if (!bh) {
219 { 214 udf_debug("block=%d, location=%d: read failed\n",
220 udf_debug("block=%d, location=%d: read failed\n", block + UDF_SB_SESSION(sb), location); 215 block + UDF_SB_SESSION(sb), location);
221 return NULL; 216 return NULL;
222 } 217 }
223 218
224 tag_p = (tag *)(bh->b_data); 219 tag_p = (tag *) (bh->b_data);
225 220
226 *ident = le16_to_cpu(tag_p->tagIdent); 221 *ident = le16_to_cpu(tag_p->tagIdent);
227 222
228 if ( location != le32_to_cpu(tag_p->tagLocation) ) 223 if (location != le32_to_cpu(tag_p->tagLocation)) {
229 {
230 udf_debug("location mismatch block %u, tag %u != %u\n", 224 udf_debug("location mismatch block %u, tag %u != %u\n",
231 block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location); 225 block + UDF_SB_SESSION(sb),
226 le32_to_cpu(tag_p->tagLocation), location);
232 goto error_out; 227 goto error_out;
233 } 228 }
234 229
235 /* Verify the tag checksum */ 230 /* Verify the tag checksum */
236 checksum = 0U; 231 checksum = 0U;
237 for (i = 0; i < 4; i++) 232 for (i = 0; i < 4; i++)
238 checksum += (uint8_t)(bh->b_data[i]); 233 checksum += (uint8_t) (bh->b_data[i]);
239 for (i = 5; i < 16; i++) 234 for (i = 5; i < 16; i++)
240 checksum += (uint8_t)(bh->b_data[i]); 235 checksum += (uint8_t) (bh->b_data[i]);
241 if (checksum != tag_p->tagChecksum) { 236 if (checksum != tag_p->tagChecksum) {
242 printk(KERN_ERR "udf: tag checksum failed block %d\n", block); 237 printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
243 goto error_out; 238 goto error_out;
@@ -245,38 +240,39 @@ udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint1
245 240
246 /* Verify the tag version */ 241 /* Verify the tag version */
247 if (le16_to_cpu(tag_p->descVersion) != 0x0002U && 242 if (le16_to_cpu(tag_p->descVersion) != 0x0002U &&
248 le16_to_cpu(tag_p->descVersion) != 0x0003U) 243 le16_to_cpu(tag_p->descVersion) != 0x0003U) {
249 {
250 udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n", 244 udf_debug("tag version 0x%04x != 0x0002 || 0x0003 block %d\n",
251 le16_to_cpu(tag_p->descVersion), block); 245 le16_to_cpu(tag_p->descVersion), block);
252 goto error_out; 246 goto error_out;
253 } 247 }
254 248
255 /* Verify the descriptor CRC */ 249 /* Verify the descriptor CRC */
256 if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || 250 if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
257 le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), 251 le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag),
258 le16_to_cpu(tag_p->descCRCLength), 0)) 252 le16_to_cpu(tag_p->
259 { 253 descCRCLength),
254 0)) {
260 return bh; 255 return bh;
261 } 256 }
262 udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", 257 udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
263 block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength)); 258 block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC),
259 le16_to_cpu(tag_p->descCRCLength));
264 260
265error_out: 261 error_out:
266 brelse(bh); 262 brelse(bh);
267 return NULL; 263 return NULL;
268} 264}
269 265
270struct buffer_head * 266struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc,
271udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, uint16_t *ident) 267 uint32_t offset, uint16_t * ident)
272{ 268{
273 return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset), 269 return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
274 loc.logicalBlockNum + offset, ident); 270 loc.logicalBlockNum + offset, ident);
275} 271}
276 272
277void udf_update_tag(char *data, int length) 273void udf_update_tag(char *data, int length)
278{ 274{
279 tag *tptr = (tag *)data; 275 tag *tptr = (tag *) data;
280 int i; 276 int i;
281 277
282 length -= sizeof(tag); 278 length -= sizeof(tag);
@@ -285,15 +281,15 @@ void udf_update_tag(char *data, int length)
285 tptr->descCRCLength = cpu_to_le16(length); 281 tptr->descCRCLength = cpu_to_le16(length);
286 tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0)); 282 tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0));
287 283
288 for (i=0; i<16; i++) 284 for (i = 0; i < 16; i++)
289 if (i != 4) 285 if (i != 4)
290 tptr->tagChecksum += (uint8_t)(data[i]); 286 tptr->tagChecksum += (uint8_t) (data[i]);
291} 287}
292 288
293void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum, 289void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
294 uint32_t loc, int length) 290 uint32_t loc, int length)
295{ 291{
296 tag *tptr = (tag *)data; 292 tag *tptr = (tag *) data;
297 tptr->tagIdent = cpu_to_le16(ident); 293 tptr->tagIdent = cpu_to_le16(ident);
298 tptr->descVersion = cpu_to_le16(version); 294 tptr->descVersion = cpu_to_le16(version);
299 tptr->tagSerialNum = cpu_to_le16(snum); 295 tptr->tagSerialNum = cpu_to_le16(snum);