^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/hpfs/ea.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * handling extended attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "hpfs_fn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* Remove external extended attributes. ano specifies whether a is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) direct sector where eas starts or an anode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) while (pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) char ex[4 + 255 + 1 + 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct extended_attribute *ea = (struct extended_attribute *)ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) if (pos + 4 > len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ano ? "anode" : "sectors", a, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (ea_indirect(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (ea_valuelen(ea) != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ano ? "anode" : "sectors", a, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) pos += ea->namelen + ea_valuelen(ea) + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct anode *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if ((anode = hpfs_map_anode(s, a, &bh))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) hpfs_remove_btree(s, &anode->btree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) hpfs_free_sectors(s, a, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) char *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) pr_err("out of memory for EA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) kfree(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ret[size] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void set_indirect_ea(struct super_block *s, int ano, secno a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const char *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) hpfs_ea_write(s, a, ano, 0, size, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Read an extended attribute named 'key' into the provided buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int ano, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) secno a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) char ex[4 + 255 + 1 + 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct extended_attribute *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct extended_attribute *ea_end = fnode_end_ea(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (ea_indirect(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) goto indirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ea_valuelen(ea) >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) memcpy(buf, ea_data(ea), ea_valuelen(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) buf[ea_valuelen(ea)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) a = le32_to_cpu(fnode->ea_secno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) len = le32_to_cpu(fnode->ea_size_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ano = fnode_in_anode(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) while (pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ea = (struct extended_attribute *)ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (pos + 4 > len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ano ? "anode" : "sectors", a, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ea_indirect(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) goto indirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (ea_valuelen(ea) >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) buf[ea_valuelen(ea)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) pos += ea->namelen + ea_valuelen(ea) + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) indirect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ea_len(ea) >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) buf[ea_len(ea)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Read an extended attribute named 'key' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int ano, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) secno a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct extended_attribute *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct extended_attribute *ea_end = fnode_end_ea(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ea_indirect(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) pr_err("out of memory for EA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) memcpy(ret, ea_data(ea), ea_valuelen(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret[ea_valuelen(ea)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) a = le32_to_cpu(fnode->ea_secno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) len = le32_to_cpu(fnode->ea_size_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ano = fnode_in_anode(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) while (pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) char ex[4 + 255 + 1 + 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ea = (struct extended_attribute *)ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (pos + 4 > len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ano ? "anode" : "sectors", a, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ea_indirect(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pr_err("out of memory for EA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea_valuelen(ea), ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kfree(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret[ea_valuelen(ea)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pos += ea->namelen + ea_valuelen(ea) + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Update or create extended attribute 'key' with value 'data'. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * when this ea exists, it MUST have the same size as size of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * This driver can't change sizes of eas ('cause I just don't need it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) const char *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) fnode_secno fno = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct super_block *s = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) unsigned pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int ano, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) secno a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned char h[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct extended_attribute *ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct extended_attribute *ea_end = fnode_end_ea(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (ea_indirect(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ea_len(ea) == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else if (ea_valuelen(ea) == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) memcpy(ea_data(ea), data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) a = le32_to_cpu(fnode->ea_secno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) len = le32_to_cpu(fnode->ea_size_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ano = fnode_in_anode(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) while (pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) char ex[4 + 255 + 1 + 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ea = (struct extended_attribute *)ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (pos + 4 > len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ano ? "anode" : "sectors", a, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!strcmp(ea->name, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ea_indirect(ea)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (ea_len(ea) == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ea_valuelen(ea) == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pos += ea->namelen + ea_valuelen(ea) + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (!le16_to_cpu(fnode->ea_offs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*if (le16_to_cpu(fnode->ea_size_s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) inode->i_ino, le16_to_cpu(fnode->ea_size_s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) fnode->ea_offs = cpu_to_le16(0xc4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 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) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) (unsigned long)inode->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 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) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ea = fnode_end_ea(fnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *(char *)ea = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ea->namelen = strlen(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ea->valuelen_lo = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ea->valuelen_hi = size >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) strcpy(ea->name, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) memcpy(ea_data(ea), data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) fnode->ea_size_s = cpu_to_le16(le16_to_cpu(fnode->ea_size_s) + strlen(key) + size + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* Most the code here is 99.9993422% unused. I hope there are no bugs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) But what .. HPFS.IFS has also bugs in ea management. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (le16_to_cpu(fnode->ea_size_s) && !le32_to_cpu(fnode->ea_size_l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) secno n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (!(n = hpfs_alloc_sector(s, fno, 1, 0))) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!(data = hpfs_get_sector(s, n, &bh))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) hpfs_free_sectors(s, n, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) memcpy(data, fnode_ea(fnode), le16_to_cpu(fnode->ea_size_s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) fnode->ea_size_s = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) fnode->ea_secno = cpu_to_le32(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) fnode->flags &= ~FNODE_anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mark_buffer_dirty(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) pos = le32_to_cpu(fnode->ea_size_l) + 5 + strlen(key) + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) len = (le32_to_cpu(fnode->ea_size_l) + 511) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (pos >= 30000) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) while (((pos + 511) >> 9) > len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) secno q = hpfs_alloc_sector(s, fno, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (!q) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) fnode->ea_secno = cpu_to_le32(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) fnode->flags &= ~FNODE_anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) } else if (!fnode_in_anode(fnode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Aargh... don't know how to create ea anodes :-( */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct anode *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) anode_secno a_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) anode->up = cpu_to_le32(fno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) anode->btree.fnode_parent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) anode->btree.n_free_nodes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) anode->btree.n_used_nodes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) anode->btree.first_free = cpu_to_le16(le16_to_cpu(anode->btree.first_free) + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) anode->u.external[0].disk_secno = cpu_to_le32(le32_to_cpu(fnode->ea_secno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) anode->u.external[0].file_secno = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) anode->u.external[0].length = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) mark_buffer_dirty(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fnode->flags |= FNODE_anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) fnode->ea_secno = cpu_to_le32(a_s);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) secno new_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct buffer_head *bh1, *bh2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) void *b1, *b2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!(b1 = hpfs_map_sector(s, le32_to_cpu(fnode->ea_secno) + i, &bh1, len - i - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) brelse(bh1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) memcpy(b2, b1, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) brelse(bh1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mark_buffer_dirty(bh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) brelse(bh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) fnode->ea_secno = cpu_to_le32(new_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) len = (pos + 511) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (fnode_in_anode(fnode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 0, len) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) h[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) h[1] = strlen(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) h[2] = size & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) h[3] = size >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) fnode->ea_size_l = cpu_to_le32(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (le32_to_cpu(fnode->ea_secno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (fnode_in_anode(fnode)) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 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));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)