Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

hpfs: get rid of bitfields endianness wanking in extended_attribute



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 185553b2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+17 −17
Original line number Diff line number Diff line
@@ -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;
	}
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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);
			}
@@ -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)
+16 −15
Original line number Diff line number Diff line
@@ -528,32 +528,23 @@ 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
@@ -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:
   comment-column: 40