HPFS: Fix endianity. Make hpfs work on big-endian machines

Fix endianity. Make hpfs work on big-endian machines.

Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Mikulas Patocka
2011-05-08 20:44:26 +02:00
committed by Linus Torvalds
parent bc8728ee56
commit 0b69760be6
11 changed files with 498 additions and 418 deletions

View File

@@ -24,7 +24,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
}
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
if (ea->indirect) {
if (ea->valuelen != 8) {
if (le16_to_cpu(ea->valuelen) != 8) {
hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
ano ? "anode" : "sectors", a, pos);
return;
@@ -33,7 +33,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
return;
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
}
pos += ea->namelen + ea->valuelen + 5;
pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5;
}
if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
else {
@@ -82,14 +82,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
if (!strcmp(ea->name, key)) {
if (ea->indirect)
goto indirect;
if (ea->valuelen >= size)
if (le16_to_cpu(ea->valuelen) >= size)
return -EINVAL;
memcpy(buf, ea_data(ea), ea->valuelen);
buf[ea->valuelen] = 0;
memcpy(buf, ea_data(ea), le16_to_cpu(ea->valuelen));
buf[le16_to_cpu(ea->valuelen)] = 0;
return 0;
}
a = fnode->ea_secno;
len = fnode->ea_size_l;
a = le32_to_cpu(fnode->ea_secno);
len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode;
pos = 0;
while (pos < len) {
@@ -106,14 +106,14 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
if (!strcmp(ea->name, key)) {
if (ea->indirect)
goto indirect;
if (ea->valuelen >= size)
if (le16_to_cpu(ea->valuelen) >= size)
return -EINVAL;
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf))
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), buf))
return -EIO;
buf[ea->valuelen] = 0;
buf[le16_to_cpu(ea->valuelen)] = 0;
return 0;
}
pos += ea->namelen + ea->valuelen + 5;
pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5;
}
return -ENOENT;
indirect:
@@ -138,16 +138,16 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
if (!strcmp(ea->name, key)) {
if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n");
return NULL;
}
memcpy(ret, ea_data(ea), ea->valuelen);
ret[ea->valuelen] = 0;
memcpy(ret, ea_data(ea), le16_to_cpu(ea->valuelen));
ret[le16_to_cpu(ea->valuelen)] = 0;
return ret;
}
a = fnode->ea_secno;
len = fnode->ea_size_l;
a = le32_to_cpu(fnode->ea_secno);
len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode;
pos = 0;
while (pos < len) {
@@ -164,18 +164,18 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
if (!strcmp(ea->name, key)) {
if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
if (!(ret = kmalloc((*size = le16_to_cpu(ea->valuelen)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n");
return NULL;
}
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, ret)) {
if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, le16_to_cpu(ea->valuelen), ret)) {
kfree(ret);
return NULL;
}
ret[ea->valuelen] = 0;
ret[le16_to_cpu(ea->valuelen)] = 0;
return ret;
}
pos += ea->namelen + ea->valuelen + 5;
pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5;
}
return NULL;
}
@@ -202,13 +202,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
if (ea->indirect) {
if (ea_len(ea) == size)
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
} else if (ea->valuelen == size) {
} else if (le16_to_cpu(ea->valuelen) == size) {
memcpy(ea_data(ea), data, size);
}
return;
}
a = fnode->ea_secno;
len = fnode->ea_size_l;
a = le32_to_cpu(fnode->ea_secno);
len = le32_to_cpu(fnode->ea_size_l);
ano = fnode->ea_anode;
pos = 0;
while (pos < len) {
@@ -228,41 +228,41 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
}
else {
if (ea->valuelen == size)
if (le16_to_cpu(ea->valuelen) == size)
hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
}
return;
}
pos += ea->namelen + ea->valuelen + 5;
pos += ea->namelen + le16_to_cpu(ea->valuelen) + 5;
}
if (!fnode->ea_offs) {
/*if (fnode->ea_size_s) {
if (!le16_to_cpu(fnode->ea_offs)) {
/*if (le16_to_cpu(fnode->ea_size_s)) {
hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
inode->i_ino, fnode->ea_size_s);
inode->i_ino, le16_to_cpu(fnode->ea_size_s));
return;
}*/
fnode->ea_offs = 0xc4;
fnode->ea_offs = cpu_to_le16(0xc4);
}
if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) {
if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) {
hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
(unsigned long)inode->i_ino,
fnode->ea_offs, fnode->ea_size_s);
le32_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
return;
}
if ((fnode->ea_size_s || !fnode->ea_size_l) &&
fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) {
if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5 <= 0x200) {
ea = fnode_end_ea(fnode);
*(char *)ea = 0;
ea->namelen = strlen(key);
ea->valuelen = size;
ea->valuelen = cpu_to_le16(size);
strcpy(ea->name, key);
memcpy(ea_data(ea), data, size);
fnode->ea_size_s += strlen(key) + size + 5;
fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
goto ret;
}
/* Most the code here is 99.9993422% unused. I hope there are no bugs.
But what .. HPFS.IFS has also bugs in ea management. */
if (fnode->ea_size_s && !fnode->ea_size_l) {
if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
secno n;
struct buffer_head *bh;
char *data;
@@ -271,25 +271,26 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
hpfs_free_sectors(s, n, 1);
return;
}
memcpy(data, fnode_ea(fnode), fnode->ea_size_s);
fnode->ea_size_l = fnode->ea_size_s;
fnode->ea_size_s = 0;
fnode->ea_secno = n;
fnode->ea_anode = 0;
memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
fnode->ea_size_s = cpu_to_le16(0);
fnode->ea_secno = cpu_to_le32(n);
fnode->ea_anode = cpu_to_le32(0);
mark_buffer_dirty(bh);
brelse(bh);
}
pos = fnode->ea_size_l + 5 + strlen(key) + size;
len = (fnode->ea_size_l + 511) >> 9;
pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
if (pos >= 30000) goto bail;
while (((pos + 511) >> 9) > len) {
if (!len) {
if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0)))
goto bail;
secno q = hpfs_alloc_sector(s, fno, 1, 0);
if (!q) goto bail;
fnode->ea_secno = cpu_to_le32(q);
fnode->ea_anode = 0;
len++;
} else if (!fnode->ea_anode) {
if (hpfs_alloc_if_possible(s, fnode->ea_secno + len)) {
if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
len++;
} else {
/* Aargh... don't know how to create ea anodes :-( */
@@ -298,18 +299,18 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
anode_secno a_s;
if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
goto bail;
anode->up = fno;
anode->up = cpu_to_le32(fno);
anode->btree.fnode_parent = 1;
anode->btree.n_free_nodes--;
anode->btree.n_used_nodes++;
anode->btree.first_free += 12;
anode->u.external[0].disk_secno = fnode->ea_secno;
anode->u.external[0].file_secno = 0;
anode->u.external[0].length = len;
anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
anode->u.external[0].file_secno = cpu_to_le32(0);
anode->u.external[0].length = cpu_to_le32(len);
mark_buffer_dirty(bh);
brelse(bh);
fnode->ea_anode = 1;
fnode->ea_secno = a_s;*/
fnode->ea_secno = cpu_to_le32(a_s);*/
secno new_sec;
int i;
if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
@@ -317,7 +318,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
for (i = 0; i < len; i++) {
struct buffer_head *bh1, *bh2;
void *b1, *b2;
if (!(b1 = hpfs_map_sector(s, fnode->ea_secno + i, &bh1, len - i - 1))) {
if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
goto bail;
}
@@ -331,13 +332,13 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
mark_buffer_dirty(bh2);
brelse(bh2);
}
hpfs_free_sectors(s, fnode->ea_secno, len);
fnode->ea_secno = new_sec;
hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
fnode->ea_secno = cpu_to_le32(new_sec);
len = (pos + 511) >> 9;
}
}
if (fnode->ea_anode) {
if (hpfs_add_sector_to_btree(s, fnode->ea_secno,
if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
0, len) != -1) {
len++;
} else {
@@ -349,17 +350,17 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
h[1] = strlen(key);
h[2] = size & 0xff;
h[3] = size >> 8;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l, 4, h)) goto bail;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 4, h[1] + 1, key)) goto bail;
if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) goto bail;
fnode->ea_size_l = pos;
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
fnode->ea_size_l = cpu_to_le32(pos);
ret:
hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
return;
bail:
if (fnode->ea_secno)
if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (fnode->ea_size_l + 511) >> 9);
else hpfs_free_sectors(s, fnode->ea_secno + ((fnode->ea_size_l + 511) >> 9), len - ((fnode->ea_size_l + 511) >> 9));
else fnode->ea_secno = fnode->ea_size_l = 0;
if (le32_to_cpu(fnode->ea_secno))
if (fnode->ea_anode) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9));
else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
}