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:
committed by
Linus Torvalds
parent
bc8728ee56
commit
0b69760be6
129
fs/hpfs/ea.c
129
fs/hpfs/ea.c
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user