Skip to content

Commit

Permalink
hpfs: get rid of bitfields endianness wanking in extended_attribute
Browse files Browse the repository at this point in the history
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed May 30, 2012
1 parent 185553b commit 4085e15
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
4 changes: 2 additions & 2 deletions fs/hpfs/anode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (ea->indirect)
hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
if (ea_indirect(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));
brelse(bh);
hpfs_free_sectors(s, fno, 1);
Expand Down
34 changes: 17 additions & 17 deletions fs/hpfs/ea.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
return;
}
if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
if (ea->indirect) {
if (ea_indirect(ea)) {
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);
return;
}
if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
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;
}
Expand Down Expand Up @@ -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);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) {
if (ea->indirect)
if (ea_indirect(ea))
goto indirect;
if (ea_valuelen(ea) >= size)
return -EINVAL;
Expand All @@ -101,10 +101,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
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;
if (!strcmp(ea->name, key)) {
if (ea->indirect)
if (ea_indirect(ea))
goto indirect;
if (ea_valuelen(ea) >= size)
return -EINVAL;
Expand All @@ -119,7 +119,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
indirect:
if (ea_len(ea) >= size)
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;
buf[ea_len(ea)] = 0;
return 0;
Expand All @@ -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);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) {
if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (ea_indirect(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))) {
printk("HPFS: out of memory for EA\n");
return NULL;
Expand All @@ -159,11 +159,11 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
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;
if (!strcmp(ea->name, key)) {
if (ea->indirect)
return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
if (ea_indirect(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))) {
printk("HPFS: out of memory for EA\n");
return NULL;
Expand Down Expand Up @@ -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);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
if (!strcmp(ea->name, key)) {
if (ea->indirect) {
if (ea_indirect(ea)) {
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) {
memcpy(ea_data(ea), data, size);
}
Expand All @@ -220,12 +220,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
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;
if (!strcmp(ea->name, key)) {
if (ea->indirect) {
if (ea_indirect(ea)) {
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)
Expand Down
31 changes: 16 additions & 15 deletions fs/hpfs/hpfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,39 +528,40 @@ struct anode
run, or in multiple runs. Flags in the fnode tell whether the EA list
is immediate, in a single run, or in multiple runs. */

enum {EA_indirect = 1, EA_anode = 2, EA_needea = 128 };
struct extended_attribute
{
#ifdef __LITTLE_ENDIAN
u8 indirect: 1; /* 1 -> value gives sector number
u8 flags; /* bit 0 set -> value gives sector number
where real value starts */
u8 anode: 1; /* 1 -> 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
/* bit 1 set -> sector is an anode
that points to fragmented value */
u8 indirect: 1; /* 1 -> value gives sector number
where real value starts */
#endif
/* bit 7 set -> required ea */
u8 namelen; /* length of name, bytes */
u8 valuelen_lo; /* length of value, bytes */
u8 valuelen_hi; /* length of value, bytes */
u8 name[0];
u8 name[];
/*
u8 name[namelen]; ascii attrib name
u8 nul; terminating '\0', not counted
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
secno secno; sector address where it starts
if this.anode, the above sector number is the root of an anode tree
which points to the value.
*/
};

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:
comment-column: 40
Expand Down

0 comments on commit 4085e15

Please sign in to comment.