patch-2.3.32 linux/fs/hpfs/ea.c

Next file: linux/fs/hpfs/file.c
Previous file: linux/fs/ext2/symlink.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.31/linux/fs/hpfs/ea.c linux/fs/hpfs/ea.c
@@ -69,8 +69,64 @@
 	hpfs_ea_write(s, a, ano, 0, size, data);
 }
 
-/* Read an extended attribute named 'key' */
+/* Read an extended attribute named 'key' into the provided buffer */
+
+int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
+		char *buf, int size)
+{
+	unsigned pos;
+	int ano, len;
+	secno a;
+	struct extended_attribute *ea;
+	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)
+				goto indirect;
+			if (ea->valuelen >= size)
+				return -EINVAL;
+			memcpy(buf, ea_data(ea), ea->valuelen);
+			buf[ea->valuelen] = 0;
+			return 0;
+		}
+	a = fnode->ea_secno;
+	len = fnode->ea_size_l;
+	ano = fnode->ea_anode;
+	pos = 0;
+	while (pos < len) {
+		char ex[4 + 255 + 1 + 8];
+		ea = (struct extended_attribute *)ex;
+		if (pos + 4 > len) {
+			hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
+				ano ? "anode" : "sectors", a, len);
+			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))
+			return -EIO;
+		if (!strcmp(ea->name, key)) {
+			if (ea->indirect)
+				goto indirect;
+			if (ea->valuelen >= size)
+				return -EINVAL;
+			if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf))
+				return -EIO;
+			buf[ea->valuelen] = 0;
+			return 0;
+		}
+		pos += ea->namelen + ea->valuelen + 5;
+	}
+	return -ENOENT;
+indirect:
+	if (ea_len(ea) >= size)
+		return -EINVAL;
+	if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf))
+		return -EIO;
+	buf[ea_len(ea)] = 0;
+	return 0;
+}
 
+/* Read an extended attribute named 'key' */
 char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
 {
 	char *ret;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)