aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>2011-05-08 14:44:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-09 12:04:24 -0400
commitd0969d1949cc67a0f100f30ad69ec7ec1eca70d2 (patch)
tree70b04ebba74aff1c4df3e8cc213a7be721550fe8
parent0b69760be6968c528869d4aec95ecf64dbf3e8bd (diff)
HPFS: Fix some unaligned accesses
Fix some unaligned accesses Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/hpfs/ea.c41
-rw-r--r--fs/hpfs/hpfs.h3
-rw-r--r--fs/hpfs/hpfs_fn.h12
3 files changed, 32 insertions, 24 deletions
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c
index 1bbc37ddff40..7f1d90ca5eeb 100644
--- a/fs/hpfs/ea.c
+++ b/fs/hpfs/ea.c
@@ -24,7 +24,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
24 } 24 }
25 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; 25 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
26 if (ea->indirect) { 26 if (ea->indirect) {
27 if (le16_to_cpu(ea->valuelen) != 8) { 27 if (ea_valuelen(ea) != 8) {
28 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", 28 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
29 ano ? "anode" : "sectors", a, pos); 29 ano ? "anode" : "sectors", a, pos);
30 return; 30 return;
@@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
33 return; 33 return;
34 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); 34 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
35 } 35 }
36 pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 36 pos += ea->namelen + ea_valuelen(ea) + 5;
37 } 37 }
38 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9); 38 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
39 else { 39 else {
@@ -82,10 +82,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
82 if (!strcmp(ea->name, key)) { 82 if (!strcmp(ea->name, key)) {
83 if (ea->indirect) 83 if (ea->indirect)
84 goto indirect; 84 goto indirect;
85 if (le16_to_cpu(ea->valuelen) >= size) 85 if (ea_valuelen(ea) >= size)
86 return -EINVAL; 86 return -EINVAL;
87 memcpy(buf, ea_data(ea), le16_to_cpu(ea->valuelen)); 87 memcpy(buf, ea_data(ea), ea_valuelen(ea));
88 buf[le16_to_cpu(ea->valuelen)] = 0; 88 buf[ea_valuelen(ea)] = 0;
89 return 0; 89 return 0;
90 } 90 }
91 a = le32_to_cpu(fnode->ea_secno); 91 a = le32_to_cpu(fnode->ea_secno);
@@ -106,14 +106,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
106 if (!strcmp(ea->name, key)) { 106 if (!strcmp(ea->name, key)) {
107 if (ea->indirect) 107 if (ea->indirect)
108 goto indirect; 108 goto indirect;
109 if (le16_to_cpu(ea->valuelen) >= size) 109 if (ea_valuelen(ea) >= size)
110 return -EINVAL; 110 return -EINVAL;
111 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), buf)) 111 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
112 return -EIO; 112 return -EIO;
113 buf[le16_to_cpu(ea->valuelen)] = 0; 113 buf[ea_valuelen(ea)] = 0;
114 return 0; 114 return 0;
115 } 115 }
116 pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 116 pos += ea->namelen + ea_valuelen(ea) + 5;
117 } 117 }
118 return -ENOENT; 118 return -ENOENT;
119indirect: 119indirect:
@@ -138,12 +138,12 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
138 if (!strcmp(ea->name, key)) { 138 if (!strcmp(ea->name, key)) {
139 if (ea->indirect) 139 if (ea->indirect)
140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
141 if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) { 141 if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
142 printk("HPFS: out of memory for EA\n"); 142 printk("HPFS: out of memory for EA\n");
143 return NULL; 143 return NULL;
144 } 144 }
145 memcpy(ret, ea_data(ea), le16_to_cpu(ea->valuelen)); 145 memcpy(ret, ea_data(ea), ea_valuelen(ea));
146 ret[le16_to_cpu(ea->valuelen)] = 0; 146 ret[ea_valuelen(ea)] = 0;
147 return ret; 147 return ret;
148 } 148 }
149 a = le32_to_cpu(fnode->ea_secno); 149 a = le32_to_cpu(fnode->ea_secno);
@@ -164,18 +164,18 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
164 if (!strcmp(ea->name, key)) { 164 if (!strcmp(ea->name, key)) {
165 if (ea->indirect) 165 if (ea->indirect)
166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); 166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
167 if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) { 167 if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
168 printk("HPFS: out of memory for EA\n"); 168 printk("HPFS: out of memory for EA\n");
169 return NULL; 169 return NULL;
170 } 170 }
171 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), ret)) { 171 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
172 kfree(ret); 172 kfree(ret);
173 return NULL; 173 return NULL;
174 } 174 }
175 ret[le16_to_cpu(ea->valuelen)] = 0; 175 ret[ea_valuelen(ea)] = 0;
176 return ret; 176 return ret;
177 } 177 }
178 pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 178 pos += ea->namelen + ea_valuelen(ea) + 5;
179 } 179 }
180 return NULL; 180 return NULL;
181} 181}
@@ -202,7 +202,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
202 if (ea->indirect) { 202 if (ea->indirect) {
203 if (ea_len(ea) == size) 203 if (ea_len(ea) == size)
204 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 204 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
205 } else if (le16_to_cpu(ea->valuelen) == size) { 205 } else if (ea_valuelen(ea) == size) {
206 memcpy(ea_data(ea), data, size); 206 memcpy(ea_data(ea), data, size);
207 } 207 }
208 return; 208 return;
@@ -228,12 +228,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
228 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); 228 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
229 } 229 }
230 else { 230 else {
231 if (le16_to_cpu(ea->valuelen) == size) 231 if (ea_valuelen(ea) == size)
232 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data); 232 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
233 } 233 }
234 return; 234 return;
235 } 235 }
236 pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5; 236 pos += ea->namelen + ea_valuelen(ea) + 5;
237 } 237 }
238 if (!le16_to_cpu(fnode->ea_offs)) { 238 if (!le16_to_cpu(fnode->ea_offs)) {
239 /*if (le16_to_cpu(fnode->ea_size_s)) { 239 /*if (le16_to_cpu(fnode->ea_size_s)) {
@@ -254,7 +254,8 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
254 ea = fnode_end_ea(fnode); 254 ea = fnode_end_ea(fnode);
255 *(char *)ea = 0; 255 *(char *)ea = 0;
256 ea->namelen = strlen(key); 256 ea->namelen = strlen(key);
257 ea->valuelen = cpu_to_le16(size); 257 ea->valuelen_lo = size;
258 ea->valuelen_hi = size >> 8;
258 strcpy(ea->name, key); 259 strcpy(ea->name, key);
259 memcpy(ea_data(ea), data, size); 260 memcpy(ea_data(ea), data, size);
260 fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5); 261 fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h
index 91a6223893f9..8b0650aae328 100644
--- a/fs/hpfs/hpfs.h
+++ b/fs/hpfs/hpfs.h
@@ -546,7 +546,8 @@ struct extended_attribute
546 where real value starts */ 546 where real value starts */
547#endif 547#endif
548 u8 namelen; /* length of name, bytes */ 548 u8 namelen; /* length of name, bytes */
549 u16 valuelen; /* length of value, bytes */ 549 u8 valuelen_lo; /* length of value, bytes */
550 u8 valuelen_hi; /* length of value, bytes */
550 u8 name[0]; 551 u8 name[0];
551 /* 552 /*
552 u8 name[namelen]; ascii attrib name 553 u8 name[namelen]; ascii attrib name
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index f99377306b13..dd552f862c8f 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -13,6 +13,7 @@
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <asm/unaligned.h>
16 17
17#include "hpfs.h" 18#include "hpfs.h"
18 19
@@ -135,19 +136,24 @@ static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode)
135 return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s)); 136 return (struct extended_attribute *)((char *)fnode + le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s));
136} 137}
137 138
139static unsigned ea_valuelen(struct extended_attribute *ea)
140{
141 return ea->valuelen_lo + 256 * ea->valuelen_hi;
142}
143
138static inline struct extended_attribute *next_ea(struct extended_attribute *ea) 144static inline struct extended_attribute *next_ea(struct extended_attribute *ea)
139{ 145{
140 return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + le16_to_cpu(ea->valuelen)); 146 return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea_valuelen(ea));
141} 147}
142 148
143static inline secno ea_sec(struct extended_attribute *ea) 149static inline secno ea_sec(struct extended_attribute *ea)
144{ 150{
145 return le32_to_cpu(*((secno *)((char *)ea + 9 + ea->namelen))); 151 return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen)));
146} 152}
147 153
148static inline secno ea_len(struct extended_attribute *ea) 154static inline secno ea_len(struct extended_attribute *ea)
149{ 155{
150 return le32_to_cpu(*((secno *)((char *)ea + 5 + ea->namelen))); 156 return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen)));
151} 157}
152 158
153static inline char *ea_data(struct extended_attribute *ea) 159static inline char *ea_data(struct extended_attribute *ea)