Commit 4085e155 authored by Al Viro's avatar Al Viro

hpfs: get rid of bitfields endianness wanking in extended_attribute

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 185553b2
...@@ -483,8 +483,8 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno) ...@@ -483,8 +483,8 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno)); else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno));
ea_end = fnode_end_ea(fnode); ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (ea->indirect) if (ea_indirect(ea))
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l)); hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l));
brelse(bh); brelse(bh);
hpfs_free_sectors(s, fno, 1); hpfs_free_sectors(s, fno, 1);
......
...@@ -23,15 +23,15 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) ...@@ -23,15 +23,15 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
return; return;
} }
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
if (ea->indirect) { if (ea_indirect(ea)) {
if (ea_valuelen(ea) != 8) { if (ea_valuelen(ea) != 8) {
hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
ano ? "anode" : "sectors", a, pos); ano ? "anode" : "sectors", a, pos);
return; return;
} }
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4)) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
return; return;
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
} }
pos += ea->namelen + ea_valuelen(ea) + 5; pos += ea->namelen + ea_valuelen(ea) + 5;
} }
...@@ -81,7 +81,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, ...@@ -81,7 +81,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
struct extended_attribute *ea_end = fnode_end_ea(fnode); struct extended_attribute *ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea_indirect(ea))
goto indirect; goto indirect;
if (ea_valuelen(ea) >= size) if (ea_valuelen(ea) >= size)
return -EINVAL; return -EINVAL;
...@@ -101,10 +101,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, ...@@ -101,10 +101,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
return -EIO; return -EIO;
} }
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO; if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
return -EIO; return -EIO;
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea_indirect(ea))
goto indirect; goto indirect;
if (ea_valuelen(ea) >= size) if (ea_valuelen(ea) >= size)
return -EINVAL; return -EINVAL;
...@@ -119,7 +119,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, ...@@ -119,7 +119,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
indirect: indirect:
if (ea_len(ea) >= size) if (ea_len(ea) >= size)
return -EINVAL; return -EINVAL;
if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf)) if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
return -EIO; return -EIO;
buf[ea_len(ea)] = 0; buf[ea_len(ea)] = 0;
return 0; return 0;
...@@ -136,8 +136,8 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si ...@@ -136,8 +136,8 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
struct extended_attribute *ea_end = fnode_end_ea(fnode); struct extended_attribute *ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea_indirect(ea))
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n"); printk("HPFS: out of memory for EA\n");
return NULL; return NULL;
...@@ -159,11 +159,11 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si ...@@ -159,11 +159,11 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
return NULL; return NULL;
} }
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL; if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
return NULL; return NULL;
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) if (ea_indirect(ea))
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
printk("HPFS: out of memory for EA\n"); printk("HPFS: out of memory for EA\n");
return NULL; return NULL;
...@@ -199,9 +199,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -199,9 +199,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
struct extended_attribute *ea_end = fnode_end_ea(fnode); struct extended_attribute *ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) { if (ea_indirect(ea)) {
if (ea_len(ea) == size) if (ea_len(ea) == size)
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
} else if (ea_valuelen(ea) == size) { } else if (ea_valuelen(ea) == size) {
memcpy(ea_data(ea), data, size); memcpy(ea_data(ea), data, size);
} }
...@@ -220,12 +220,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, ...@@ -220,12 +220,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
return; return;
} }
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
return; return;
if (!strcmp(ea->name, key)) { if (!strcmp(ea->name, key)) {
if (ea->indirect) { if (ea_indirect(ea)) {
if (ea_len(ea) == size) if (ea_len(ea) == size)
set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
} }
else { else {
if (ea_valuelen(ea) == size) if (ea_valuelen(ea) == size)
......
...@@ -528,32 +528,23 @@ struct anode ...@@ -528,32 +528,23 @@ struct anode
run, or in multiple runs. Flags in the fnode tell whether the EA list run, or in multiple runs. Flags in the fnode tell whether the EA list
is immediate, in a single run, or in multiple runs. */ is immediate, in a single run, or in multiple runs. */
enum {EA_indirect = 1, EA_anode = 2, EA_needea = 128 };
struct extended_attribute struct extended_attribute
{ {
#ifdef __LITTLE_ENDIAN u8 flags; /* bit 0 set -> value gives sector number
u8 indirect: 1; /* 1 -> value gives sector number
where real value starts */ where real value starts */
u8 anode: 1; /* 1 -> sector is an anode /* bit 1 set -> sector is an anode
that points to fragmented value */
u8 flag23456: 5;
u8 needea: 1; /* required ea */
#else
u8 needea: 1; /* required ea */
u8 flag23456: 5;
u8 anode: 1; /* 1 -> sector is an anode
that points to fragmented value */ that points to fragmented value */
u8 indirect: 1; /* 1 -> value gives sector number /* bit 7 set -> required ea */
where real value starts */
#endif
u8 namelen; /* length of name, bytes */ u8 namelen; /* length of name, bytes */
u8 valuelen_lo; /* length of value, bytes */ u8 valuelen_lo; /* length of value, bytes */
u8 valuelen_hi; /* length of value, bytes */ u8 valuelen_hi; /* length of value, bytes */
u8 name[0]; u8 name[];
/* /*
u8 name[namelen]; ascii attrib name u8 name[namelen]; ascii attrib name
u8 nul; terminating '\0', not counted u8 nul; terminating '\0', not counted
u8 value[valuelen]; value, arbitrary u8 value[valuelen]; value, arbitrary
if this.indirect, valuelen is 8 and the value is if this.flags & 1, valuelen is 8 and the value is
u32 length; real length of value, bytes u32 length; real length of value, bytes
secno secno; sector address where it starts secno secno; sector address where it starts
if this.anode, the above sector number is the root of an anode tree if this.anode, the above sector number is the root of an anode tree
...@@ -561,6 +552,16 @@ struct extended_attribute ...@@ -561,6 +552,16 @@ struct extended_attribute
*/ */
}; };
static inline bool ea_indirect(struct extended_attribute *ea)
{
return ea->flags & EA_indirect;
}
static inline bool ea_in_anode(struct extended_attribute *ea)
{
return ea->flags & EA_anode;
}
/* /*
Local Variables: Local Variables:
comment-column: 40 comment-column: 40
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment